home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / phpMyAdmin / libraries / common.lib.php < prev    next >
PHP Script  |  2005-05-03  |  102KB  |  2,565 lines

  1. <?php
  2. /* $Id: common.lib.php,v 2.128.2.3 2005/05/03 22:52:51 lem9 Exp $ */
  3. // vim: expandtab sw=4 ts=4 sts=4:
  4.  
  5. /**
  6.  * Misc stuff and functions used by almost all the scripts.
  7.  * Among other things, it contains the advanced authentification work.
  8.  */
  9.  
  10. /**
  11.  * Order of sections for common.lib.php:
  12.  *
  13.  * some functions need the constants of libraries/defines.lib.php
  14.  * and defines_mysql.lib.php
  15.  *
  16.  * the PMA_setFontSizes() function must be before the call to the
  17.  * libraries/auth/cookie.auth.lib.php library
  18.  *
  19.  * the include of libraries/defines_mysql.lib.php must be after the connection
  20.  * to db to get the MySql version
  21.  *
  22.  * the PMA_sqlAddslashes() function must be before the connection to db
  23.  *
  24.  * the authentication libraries must be before the connection to db but
  25.  * after the PMA_isInto() function
  26.  *
  27.  * the PMA_mysqlDie() function must be before the connection to db but
  28.  * after mysql extension has been loaded
  29.  *
  30.  * the PMA_mysqlDie() function needs the PMA_format_sql() Function
  31.  *
  32.  * ... so the required order is:
  33.  *
  34.  * - parsing of the configuration file
  35.  * - load of the libraries/defines.lib.php library
  36.  * - load of mysql extension (if necessary)
  37.  * - definition of PMA_sqlAddslashes()
  38.  * - definition of PMA_format_sql()
  39.  * - definition of PMA_mysqlDie()
  40.  * - definition of PMA_isInto()
  41.  * - definition of PMA_setFontSizes()
  42.  * - loading of an authentication library
  43.  * - db connection
  44.  * - authentication work
  45.  * - load of the libraries/defines_mysql.lib.php library to get the MySQL
  46.  *   release number
  47.  * - other functions, respecting dependencies
  48.  */
  49.  
  50. /**
  51.  * Minimum inclusion? (i.e. for the stylesheet builder)
  52.  */
  53.  
  54. if (!isset($is_minimum_common)) {
  55.     $is_minimum_common = FALSE;
  56. }
  57.  
  58. /**
  59.  * Avoids undefined variables
  60.  */
  61. if (!isset($use_backquotes)) {
  62.     $use_backquotes   = 0;
  63. }
  64. if (!isset($pos)) {
  65.     $pos              = 0;
  66. }
  67.  
  68. /**
  69.  * 2004-06-30 rabus: Ensure, that $cfg variables are not set somwhere else
  70.  * before including the config file.
  71.  */
  72. unset($cfg);
  73.  
  74. /**
  75.  * Detects the config file we want to load
  76.  */
  77. if (file_exists('./config.inc.developer.php')) {
  78.     $cfgfile_to_load = './config.inc.developer.php';
  79. } else {
  80.     $cfgfile_to_load = './config.inc.php';
  81. }
  82.  
  83. /**
  84.  * Parses the configuration file and gets some constants used to define
  85.  * versions of phpMyAdmin/php/mysql...
  86.  */
  87. $old_error_reporting = error_reporting(0);
  88. include_once($cfgfile_to_load);
  89. // Include failed
  90. if (!isset($cfgServers) && !isset($cfg['Servers'])) {
  91.     // Creates fake settings
  92.     $cfg = array('DefaultLang'           => 'en-iso-8859-1',
  93.                     'AllowAnywhereRecoding' => FALSE);
  94.     // Loads the language file
  95.     require_once('./libraries/select_lang.lib.php');
  96.     // Sends the Content-Type header
  97.     header('Content-Type: text/html; charset=' . $charset);
  98.     // Displays the error message
  99.     ?>
  100. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  101. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  102. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $available_languages[$lang][2]; ?>" lang="<?php echo $available_languages[$lang][2]; ?>" dir="<?php echo $text_dir; ?>">
  103.  
  104. <head>
  105. <title>phpMyAdmin</title>
  106. <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $charset; ?>" />
  107.  
  108. <style type="text/css">
  109. <!--
  110. body  {font-family: sans-serif; font-size: small; color: #000000; background-color: #F5F5F5}
  111. h1    {font-family: sans-serif; font-size: large; font-weight: bold}
  112. //-->
  113. </style>
  114. </head>
  115.  
  116.  
  117. <body bgcolor="#ffffff">
  118. <h1>phpMyAdmin - <?php echo $strError; ?></h1>
  119. <p>
  120. <?php echo $strConfigFileError; ?><br /><br />
  121. <a href="config.inc.php" target="_blank">config.inc.php</a>
  122. </p>
  123. </body>
  124.  
  125. </html>
  126.     <?php
  127.     exit();
  128. }
  129. error_reporting($old_error_reporting);
  130. unset($old_error_reporting, $cfgfile_to_load);
  131.  
  132. /**
  133.  * Includes compatibility code for older config.inc.php revisions
  134.  * if necessary
  135.  */
  136. if (isset($cfg['FileRevision'])) {
  137.     // converting revision string into an array
  138.     //     e.g. "Revision: 2.0" becomes array(2, 0).
  139.     $cfg['FileRevision'] = str_replace('$' . 'Revision: ', '', $cfg['FileRevision']);
  140.     $cfg['FileRevision'] = str_replace(' $', '', $cfg['FileRevision']);
  141.     $cfg['FileRevision'] = explode('.', $cfg['FileRevision']);
  142. } else {
  143.     $cfg['FileRevision'] = array(1, 1);
  144. }
  145. if ($cfg['FileRevision'][0] < 2 || ($cfg['FileRevision'][0] == 2 && $cfg['FileRevision'][1] < 52)) {
  146.     require_once('./libraries/config_import.lib.php');
  147. }
  148.  
  149. /**
  150.  * Includes the language file if it hasn't been included yet
  151.  */
  152. require_once('./libraries/select_lang.lib.php');
  153. /**
  154.  * Gets constants that defines the PHP version number.
  155.  * This include must be located physically before any code that needs to
  156.  * reference the constants, else PHP 3.0.16 won't be happy.
  157.  */
  158. require_once('./libraries/defines.lib.php');
  159.  
  160.  
  161. /**
  162.  * Sanitizes $message, taking into account our special codes
  163.  * for formatting
  164.  *
  165.  * @param   string   the message
  166.  *
  167.  * @return  string   the sanitized message
  168.  *
  169.  * @access  public
  170.  */
  171. function PMA_sanitize($message)
  172. {
  173.     $replace_pairs = array(
  174.         '<'     => '<',
  175.         '>'     => '>',
  176.         '[i]'   => '<i>',
  177.         '[/i]'  => '</i>',
  178.         '[b]'   => '<b>',
  179.         '[br]'  => '<br />',
  180.         '[/b]'  => '</b>',
  181.     );
  182.     return strtr($message, $replace_pairs);
  183. }
  184.  
  185. // XSS
  186. if (isset($convcharset)) {
  187.     $convcharset = PMA_sanitize($convcharset);
  188. }
  189.  
  190. if ($is_minimum_common == FALSE) {
  191.     /**
  192.      * Define $is_upload
  193.      */
  194.  
  195.       $is_upload = TRUE;
  196.       if (strtolower(@ini_get('file_uploads')) == 'off'
  197.              || @ini_get('file_uploads') == 0) {
  198.           $is_upload = FALSE;
  199.       }
  200.  
  201.     /**
  202.      * Maximum upload size as limited by PHP
  203.      * Used with permission from Moodle (http://moodle.org) by Martin Dougiamas
  204.      *
  205.      * this section generates $max_upload_size in bytes
  206.      */
  207.  
  208.     function get_real_size($size=0) {
  209.     /// Converts numbers like 10M into bytes
  210.         if (!$size) {
  211.             return 0;
  212.         }
  213.         $scan['MB'] = 1048576;
  214.         $scan['Mb'] = 1048576;
  215.         $scan['M'] = 1048576;
  216.         $scan['m'] = 1048576;
  217.         $scan['KB'] = 1024;
  218.         $scan['Kb'] = 1024;
  219.         $scan['K'] = 1024;
  220.         $scan['k'] = 1024;
  221.  
  222.         while (list($key) = each($scan)) {
  223.             if ((strlen($size)>strlen($key))&&(substr($size, strlen($size) - strlen($key))==$key)) {
  224.                 $size = substr($size, 0, strlen($size) - strlen($key)) * $scan[$key];
  225.                 break;
  226.             }
  227.         }
  228.         return $size;
  229.     } // end function
  230.  
  231.  
  232.     if (!$filesize = ini_get('upload_max_filesize')) {
  233.         $filesize = "5M";
  234.     }
  235.     $max_upload_size = get_real_size($filesize);
  236.  
  237.     if ($postsize = ini_get('post_max_size')) {
  238.         $postsize = get_real_size($postsize);
  239.         if ($postsize < $max_upload_size) {
  240.             $max_upload_size = $postsize;
  241.         }
  242.     }
  243.     unset($filesize);
  244.     unset($postsize);
  245.  
  246.     /**
  247.      * other functions for maximum upload work
  248.      */
  249.  
  250.     /**
  251.      * Displays the maximum size for an upload
  252.      *
  253.      * @param   integer  the size
  254.      *
  255.      * @return  string   the message
  256.      *
  257.      * @access  public
  258.      */
  259.      function PMA_displayMaximumUploadSize($max_upload_size) {
  260.          list($max_size, $max_unit) = PMA_formatByteDown($max_upload_size);
  261.          return '(' . sprintf($GLOBALS['strMaximumSize'], $max_size, $max_unit) . ')';
  262.      }
  263.  
  264.     /**
  265.      * Generates a hidden field which should indicate to the browser
  266.      * the maximum size for upload
  267.      *
  268.      * @param   integer  the size
  269.      *
  270.      * @return  string   the INPUT field
  271.      *
  272.      * @access  public
  273.      */
  274.      function PMA_generateHiddenMaxFileSize($max_size){
  275.          return '<input type="hidden" name="MAX_FILE_SIZE" value="' .$max_size . '" />';
  276.      }
  277.  
  278.     /**
  279.      * Charset conversion.
  280.      */
  281.     require_once('./libraries/charset_conversion.lib.php');
  282.  
  283.     /**
  284.      * String handling
  285.      */
  286.     require_once('./libraries/string.lib.php');
  287. }
  288.  
  289. /**
  290.  * Removes insecure parts in a path; used before include() or
  291.  * require() when a part of the path comes from an insecure source
  292.  * like a cookie or form.
  293.  *
  294.  * @param    string  The path to check
  295.  *
  296.  * @return   string  The secured path
  297.  *
  298.  * @access  public
  299.  * @author  Marc Delisle (lem9@users.sourceforge.net)
  300.  */
  301. function PMA_securePath($path) {
  302.  
  303.     // change .. to .
  304.     $path = preg_replace('@\.\.*@','.',$path);
  305.  
  306.     return $path;
  307. } // end function
  308.  
  309. // If zlib output compression is set in the php configuration file, no
  310. // output buffering should be run
  311. if (@ini_get('zlib.output_compression')) {
  312.     $cfg['OBGzip'] = FALSE;
  313. }
  314.  
  315. // disable output-buffering (if set to 'auto') for IE6, else enable it.
  316. if (strtolower($cfg['OBGzip']) == 'auto') {
  317.     if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER >= 6 && PMA_USR_BROWSER_VER < 7) {
  318.         $cfg['OBGzip'] = FALSE;
  319.     } else {
  320.         $cfg['OBGzip'] = TRUE;
  321.     }
  322. }
  323.  
  324.  
  325. /* Theme Manager
  326.  * 2004-05-20 Michael Keck (mail_at_michaelkeck_dot_de)
  327.  *            This little script checks if there're themes available
  328.  *            and if the directory $ThemePath/$theme/img/ exists
  329.  *            If not, it will use default images
  330. */
  331. // Theme Manager
  332. if (!$cfg['ThemeManager'] || !isset($_COOKIE['pma_theme']) || empty($_COOKIE['pma_theme'])){
  333.     $GLOBALS['theme'] = $cfg['ThemeDefault'];
  334.     $ThemeDefaultOk = FALSE;
  335.     if ($cfg['ThemePath']!='' && $cfg['ThemePath'] != FALSE) {
  336.         $tmp_theme_mainpath = $cfg['ThemePath'];
  337.         $tmp_theme_fullpath = $cfg['ThemePath'] . '/' .$cfg['ThemeDefault'];
  338.         if (@is_dir($tmp_theme_mainpath)) {
  339.             if (isset($cfg['ThemeDefault']) && @is_dir($tmp_theme_fullpath)) {
  340.                 $ThemeDefaultOk = TRUE;
  341.             }
  342.         }
  343.     }
  344.     if ($ThemeDefaultOk == TRUE){
  345.         $GLOBALS['theme'] = $cfg['ThemeDefault'];
  346.     } else {
  347.         $GLOBALS['theme'] = 'original';
  348.     }
  349. } else {
  350.     // if we just changed theme, we must take the new one so that
  351.     // index.php takes the correct one for height computing
  352.     if (isset($_POST['set_theme'])) {
  353.         $GLOBALS['theme'] = PMA_securePath($_POST['set_theme']);
  354.     } else {
  355.         $GLOBALS['theme'] = PMA_securePath($_COOKIE['pma_theme']);
  356.     }
  357. }
  358.  
  359. // check for theme requires/name
  360. unset($theme_name, $theme_generation, $theme_version);
  361. @include($cfg['ThemePath'] . '/' . $GLOBALS['theme'] . '/info.inc.php');
  362.  
  363. // did it set correctly?
  364. if (!isset($theme_name, $theme_generation, $theme_version))
  365.     $GLOBALS['theme'] = 'original'; // invalid theme
  366.  
  367. if ($theme_generation != PMA_THEME_GENERATION)
  368.     $GLOBALS['theme'] = 'original'; // different generation
  369.  
  370. if ($theme_version < PMA_THEME_VERSION)
  371.     $GLOBALS['theme'] = 'original'; // too old version
  372.  
  373. $pmaThemeImage  = $cfg['ThemePath'] . '/' . $GLOBALS['theme'] . '/img/';
  374. $tmp_layout_file = $cfg['ThemePath'] . '/' . $GLOBALS['theme'] . '/layout.inc.php';
  375. if (@file_exists($tmp_layout_file)) {
  376.     include($tmp_layout_file);
  377. }
  378. if (!is_dir($pmaThemeImage)) {
  379.     $pmaThemeImage = $cfg['ThemePath'] . '/original/img/';
  380. }
  381. // end theme manager
  382.  
  383. /**
  384.  * collation_connection
  385.  */
  386.  // (could be improved by executing it after the MySQL connection only if
  387.  //  PMA_MYSQL_INT_VERSION >= 40100 )
  388. if (isset($_COOKIE) && !empty($_COOKIE['pma_collation_connection']) && empty($_POST['collation_connection'])) {
  389.     $collation_connection = $_COOKIE['pma_collation_connection'];
  390. }
  391.  
  392.  
  393. if ($is_minimum_common == FALSE) {
  394.     /**
  395.      * Include URL/hidden inputs generating.
  396.      */
  397.     require_once('./libraries/url_generating.lib.php');
  398.  
  399.     /**
  400.      * Add slashes before "'" and "\" characters so a value containing them can
  401.      * be used in a sql comparison.
  402.      *
  403.      * @param   string   the string to slash
  404.      * @param   boolean  whether the string will be used in a 'LIKE' clause
  405.      *                   (it then requires two more escaped sequences) or not
  406.      * @param   boolean  whether to treat cr/lfs as escape-worthy entities
  407.      *                   (converts \n to \\n, \r to \\r)
  408.      *
  409.      * @return  string   the slashed string
  410.      *
  411.      * @access  public
  412.      */
  413.     function PMA_sqlAddslashes($a_string = '', $is_like = FALSE, $crlf = FALSE)
  414.     {
  415.         if ($is_like) {
  416.             $a_string = str_replace('\\', '\\\\\\\\', $a_string);
  417.         } else {
  418.             $a_string = str_replace('\\', '\\\\', $a_string);
  419.         }
  420.  
  421.         if ($crlf) {
  422.             $a_string = str_replace("\n", '\n', $a_string);
  423.             $a_string = str_replace("\r", '\r', $a_string);
  424.             $a_string = str_replace("\t", '\t', $a_string);
  425.         }
  426.  
  427.         $a_string = str_replace('\'', '\'\'', $a_string);
  428.  
  429.         return $a_string;
  430.     } // end of the 'PMA_sqlAddslashes()' function
  431.  
  432.  
  433.     /**
  434.      * Add slashes before "_" and "%" characters for using them in MySQL
  435.      * database, table and field names.
  436.      * Note: This function does not escape backslashes!
  437.      *
  438.      * @param   string   the string to escape
  439.      *
  440.      * @return  string   the escaped string
  441.      *
  442.      * @access  public
  443.      */
  444.     function PMA_escape_mysql_wildcards($name)
  445.     {
  446.         $name = str_replace('_', '\\_', $name);
  447.         $name = str_replace('%', '\\%', $name);
  448.  
  449.         return $name;
  450.     } // end of the 'PMA_escape_mysql_wildcards()' function
  451.  
  452.  
  453.     /**
  454.      * format sql strings
  455.      *
  456.      * @param   mixed    pre-parsed SQL structure
  457.      *
  458.      * @return  string   the formatted sql
  459.      *
  460.      * @global  array    the configuration array
  461.      * @global  boolean  whether the current statement is a multiple one or not
  462.      *
  463.      * @access  public
  464.      *
  465.      * @author  Robin Johnson <robbat2@users.sourceforge.net>
  466.      */
  467.     function PMA_formatSql($parsed_sql, $unparsed_sql = '')
  468.     {
  469.         global $cfg;
  470.  
  471.         // Check that we actually have a valid set of parsed data
  472.         // well, not quite
  473.         // first check for the SQL parser having hit an error
  474.         if (PMA_SQP_isError()) {
  475.             return $parsed_sql;
  476.         }
  477.         // then check for an array
  478.         if (!is_array($parsed_sql)) {
  479.             // We don't so just return the input directly
  480.             // This is intended to be used for when the SQL Parser is turned off
  481.             $formatted_sql = '<pre>' . "\n"
  482.                             . (($cfg['SQP']['fmtType'] == 'none' && $unparsed_sql != '') ? $unparsed_sql : $parsed_sql) . "\n"
  483.                             . '</pre>';
  484.             return $formatted_sql;
  485.         }
  486.  
  487.         $formatted_sql        = '';
  488.  
  489.         switch ($cfg['SQP']['fmtType']) {
  490.             case 'none':
  491.                 if ($unparsed_sql != '') {
  492.                     $formatted_sql = "<pre>\n" . PMA_SQP_formatNone(array('raw' => $unparsed_sql)) . "\n</pre>";
  493.                 } else {
  494.                     $formatted_sql = PMA_SQP_formatNone($parsed_sql);
  495.                 }
  496.                 break;
  497.             case 'html':
  498.                 $formatted_sql = PMA_SQP_formatHtml($parsed_sql,'color');
  499.                 break;
  500.             case 'text':
  501.                 //$formatted_sql = PMA_SQP_formatText($parsed_sql);
  502.                 $formatted_sql = PMA_SQP_formatHtml($parsed_sql,'text');
  503.                 break;
  504.             default:
  505.                 break;
  506.         } // end switch
  507.  
  508.         return $formatted_sql;
  509.     } // end of the "PMA_formatSql()" function
  510.  
  511.  
  512.     /**
  513.      * Displays a link to the official MySQL documentation
  514.      *
  515.      * @param   chapter of "HTML, one page per chapter" documentation
  516.      * @param   contains name of page/anchor that is being linked
  517.      *
  518.      * @return  string  the html link
  519.      *
  520.      * @access  public
  521.      */
  522. // 2004-05-04: replaced with a modified function from Michael Keck (mkkeck)
  523.         function PMA_showMySQLDocu($chapter, $link)
  524.         {
  525.  
  526.             if (!empty($GLOBALS['cfg']['MySQLManualBase'])) {
  527.                 if (!empty($GLOBALS['cfg']['MySQLManualType'])) {
  528.                     switch ($GLOBALS['cfg']['MySQLManualType']) {
  529.                         case 'old':
  530.                             if ($GLOBALS['cfg']['ReplaceHelpImg']) {
  531.                                 return '<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc"><img src="' . $GLOBALS['pmaThemeImage'] . 'b_help.png" width="11" height="11" border="0" alt="' . $GLOBALS['strDocu'] . '" title="' . $GLOBALS['strDocu'] . '" hspace="2" align="middle" /></a>';
  532.                             }else{
  533.                                 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  534.                            }
  535.                         case 'chapters':
  536.                             if ($GLOBALS['cfg']['ReplaceHelpImg']) {
  537.                                 return '<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/manual_' . $chapter . '.html#' . $link . '" target="mysql_doc"><img src="' . $GLOBALS['pmaThemeImage'] . 'b_help.png" width="11" height="11" border="0" alt="' . $GLOBALS['strDocu'] . '" title="' . $GLOBALS['strDocu'] . '" hspace="2" align="middle" /></a>';
  538.                            } else {
  539.                                return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/manual_' . $chapter . '.html#' . $link . '" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]'; }
  540.                         case 'big':
  541.                             if ($GLOBALS['cfg']['ReplaceHelpImg']) {
  542.                                 return '<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '#' . $link . '" target="mysql_doc"><img src="' . $GLOBALS['pmaThemeImage'] . 'b_help.png" width="11" height="11" border="0" alt="' . $GLOBALS['strDocu'] . '" title="' . $GLOBALS['strDocu'] . '" hspace="2" align="middle" /></a>';
  543.                             } else {
  544.                                 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '#' . $link . '" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  545.                             }
  546.                         case 'none':
  547.                             return '';
  548.                         case 'searchable':
  549.                         default:
  550.                             if ($GLOBALS['cfg']['ReplaceHelpImg']) {
  551.                                 return '<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link . '.html" target="mysql_doc"><img src="' . $GLOBALS['pmaThemeImage'] . 'b_help.png" width="11" height="11" border="0" alt="' . $GLOBALS['strDocu'] . '" title="' . $GLOBALS['strDocu'] . '" hspace="2" align="middle" /></a>';
  552.                             } else {
  553.                                 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  554.                             }
  555.                     }
  556.                 } else {
  557.                     // no Type defined, show the old one
  558.                     if ($GLOBALS['cfg']['ReplaceHelpImg']) {
  559.                         return '<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc"><img src="' . $GLOBALS['pmaThemeImage'] . 'b_help.png" width="11" height="11" border="0" alt="' . $GLOBALS['strDocu'] . '" title="' . $GLOBALS['strDocu'] . '" hspace="2" align="middle" /></a>';
  560.                     } else {
  561.                         return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  562.                     }
  563.                 }
  564.             } else {
  565.                 // no URL defined
  566.                 if (!empty($GLOBALS['cfg']['ManualBaseShort'])) {
  567.                     // the old configuration
  568.                     if ($GLOBALS['cfg']['ReplaceHelpImg']) {
  569.                         return '<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc"><img src="' . $GLOBALS['pmaThemeImage'] . 'b_help.png" width="11" height="11" border="0" alt="' . $GLOBALS['strDocu'] . '" title="' . $GLOBALS['strDocu'] . '" hspace="2" align="middle" /></a>';
  570.                     } else {
  571.                         return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
  572.                    }
  573.                 } else {
  574.                     return '';
  575.                 }
  576.             }
  577.         }
  578.                  // end of the 'PMA_showDocu()' function
  579.  
  580.     /**
  581.      * Displays a hint icon, on mouse over show the hint
  582.      *
  583.      * @param   string   the error message
  584.      *
  585.      * @access  public
  586.      */
  587.      function PMA_showHint($hint_message)
  588.      {
  589.          //return '<img class="lightbulb" src="' . $GLOBALS['pmaThemeImage'] . 'b_tipp.png" width="16" height="16" border="0" alt="' . $hint_message . '" title="' . $hint_message . '" align="middle" onclick="alert(\'' . PMA_jsFormat($hint_message, FALSE) . '\');" />';
  590.          return '<img class="lightbulb" src="' . $GLOBALS['pmaThemeImage'] . 'b_tipp.png" width="16" height="16" border="0" alt="Tip" title="Tip" align="middle" onmouseover="pmaTooltip(\'' .  PMA_jsFormat($hint_message, FALSE) . '\'); return false;" onmouseout="swapTooltip(\'default\'); return false;" />';
  591.      }
  592.  
  593.     /**
  594.      * Displays a MySQL error message in the right frame.
  595.      *
  596.      * @param   string   the error message
  597.      * @param   string   the sql query that failed
  598.      * @param   boolean  whether to show a "modify" link or not
  599.      * @param   string   the "back" link url (full path is not required)
  600.      * @param   boolean  EXIT the page?
  601.      *
  602.      * @global  array    the configuration array
  603.      *
  604.      * @access  public
  605.      */
  606.     function PMA_mysqlDie($error_message = '', $the_query = '',
  607.                             $is_modify_link = TRUE, $back_url = '',
  608.                             $exit = TRUE)
  609.     {
  610.         global $cfg, $table, $db, $sql_query;
  611.  
  612.         require_once('./header.inc.php');
  613.  
  614.         if (!$error_message) {
  615.             $error_message = PMA_DBI_getError();
  616.         }
  617.         if (!$the_query && !empty($GLOBALS['sql_query'])) {
  618.             $the_query = $GLOBALS['sql_query'];
  619.         }
  620.  
  621.         // --- Added to solve bug #641765
  622.         // Robbat2 - 12 January 2003, 9:46PM
  623.         // Revised, Robbat2 - 13 Janurary 2003, 2:59PM
  624.         if (!function_exists('PMA_SQP_isError') || PMA_SQP_isError()) {
  625.             $formatted_sql = htmlspecialchars($the_query);
  626.         } else {
  627.             $formatted_sql = PMA_formatSql(PMA_SQP_parse($the_query), $the_query);
  628.         }
  629.         // ---
  630.         echo "\n" . '<!-- PMA-SQL-ERROR -->' . "\n";
  631.         echo '    <table border="0" cellpadding="2" cellspacing="1">'
  632.            . '        <tr>' . "\n"
  633.            . '            <th class="tblHeadError"><div class="errorhead">' . $GLOBALS['strError'] . '</div></th>' . "\n"
  634.            . '        </tr>' . "\n"
  635.            . '        <tr>' . "\n"
  636.            . '            <td>';
  637.         // if the config password is wrong, or the MySQL server does not
  638.         // respond, do not show the query that would reveal the
  639.         // username/password
  640.         if (!empty($the_query) && !strstr($the_query, 'connect')) {
  641.             // --- Added to solve bug #641765
  642.             // Robbat2 - 12 January 2003, 9:46PM
  643.             // Revised, Robbat2 - 13 Janurary 2003, 2:59PM
  644.             if (function_exists('PMA_SQP_isError') && PMA_SQP_isError()) {
  645.                 echo PMA_SQP_getErrorString();
  646.             }
  647.             // ---
  648.             // modified to show me the help on sql errors (Michael Keck)
  649.             echo '<div class="tblWarn"><p>' . "\n";
  650.             echo '    <b>' . $GLOBALS['strSQLQuery'] . ':</b>' . "\n";
  651.             if (strstr(strtolower($formatted_sql),'select')) { // please show me help to the error on select
  652.                 echo PMA_showMySQLDocu('Reference', 'SELECT');
  653.             }
  654.             if ($is_modify_link && isset($db)) {
  655.                 if (isset($table)) {
  656.                     $doedit_goto = '<a href="tbl_properties.php?' . PMA_generate_common_url($db, $table) . '&sql_query=' . urlencode($the_query) . '&show_query=1">';
  657.                 } else {
  658.                     $doedit_goto = '<a href="db_details.php?' . PMA_generate_common_url($db) . '&sql_query=' . urlencode($the_query) . '&show_query=1">';
  659.                 }
  660.                 if ($GLOBALS['cfg']['PropertiesIconic']) {
  661.                     echo $doedit_goto
  662.                        . '<img src=" '. $GLOBALS['pmaThemeImage'] . 'b_edit.png" width="16" height="16" border="0" hspace="2" align="middle" alt="' . $GLOBALS['strEdit'] .'" />'
  663.                        . '</a>';
  664.                 } else {
  665.                     echo '    ['
  666.                        . $doedit_goto . $GLOBALS['strEdit'] . '</a>'
  667.                        . ']' . "\n";
  668.                 }
  669.             } // end if
  670.             echo '</p>' . "\n"
  671.                     . '<p>' . "\n"
  672.                     . '    ' . $formatted_sql . "\n"
  673.                     . '</p></div>' . "\n";
  674.         } // end if
  675.  
  676.         $tmp_mysql_error = ''; // for saving the original $error_message
  677.         if (!empty($error_message)) {
  678.             $tmp_mysql_error = strtolower($error_message); // save the original $error_message
  679.             $error_message = htmlspecialchars($error_message);
  680.             $error_message = preg_replace("@((\015\012)|(\015)|(\012)){3,}@", "\n\n", $error_message);
  681.         }
  682.         // modified to show me the help on error-returns (Michael Keck)
  683.         echo '<div class="tblWarn"><p>' . "\n"
  684.                 . '    <b>' . $GLOBALS['strMySQLSaid'] . '</b>'
  685.                 . PMA_showMySQLDocu('Error-returns', 'Error-returns')
  686.                 . "\n"
  687.                 . '</p>' . "\n";
  688.  
  689.         // The error message will be displayed within a CODE segment.
  690.         // To preserve original formatting, but allow wordwrapping, we do a couple of replacements
  691.  
  692.         // Replace all non-single blanks with their HTML-counterpart
  693.         $error_message = str_replace('  ', '  ', $error_message);
  694.         // Replace TAB-characters with their HTML-counterpart
  695.         $error_message = str_replace("\t", '    ', $error_message);
  696.         // Replace linebreaks
  697.         $error_message = nl2br($error_message);
  698.  
  699.         echo '<code>' . "\n"
  700.             . $error_message . "\n"
  701.             . '</code><br />' . "\n";
  702.  
  703.         // feature request #1036254:
  704.         // Add a link by MySQL-Error #1062 - Duplicate entry
  705.         // 2004-10-20 by mkkeck
  706.         // 2005-01-17 modified by mkkeck bugfix
  707.         if (substr($error_message, 1, 4) == '1062') {
  708.             // get the duplicate entry
  709.             $mysql_error_values = array();
  710.             $mysql_error_words  = explode(' ',$tmp_mysql_error);
  711.             foreach ($mysql_error_words as $mysql_error_word) {
  712.                 if (strstr($mysql_error_word, "'")) {
  713.                    $mysql_error_values = explode('-', preg_replace("/'/", "", $mysql_error_word));
  714.                    break; // exit 'foreach'
  715.                 }
  716.             }
  717.             $duplicate_sql_query = '';
  718.             if (isset($mysql_error_values[0])) {
  719.                 $tmp_fields = PMA_DBI_get_fields($db, $table, NULL);
  720.                 foreach ($tmp_fields as $tmp_field) {
  721.                     $duplicate_sql_query .= (($duplicate_sql_query!='') ? ' OR ' : '') . $tmp_field['Field'] . " LIKE '" . $mysql_error_values[0] . "'";
  722.                 }
  723.             }
  724.             if ($duplicate_sql_query!='') {
  725.                 $duplicate_sql_query = "SELECT * FROM " . $table . " WHERE (" . $duplicate_sql_query . ")";
  726.             } else {
  727.                 $duplicate_sql_query = "SELECT * FROM " . $table . "";
  728.             }
  729.             echo '        <form method="post" action="read_dump.php" style="padding: 0px; margin: 0px">' ."\n"
  730.                     . '            <input type="hidden" name="sql_query" value="' . $duplicate_sql_query . '" />' . "\n"
  731.                     . '            ' . PMA_generate_common_hidden_inputs($db, $table) . "\n"
  732.                     . '            <input type="submit" name="submit" value="' . $GLOBALS['strBrowse'] . '" />' . "\n"
  733.                     . '        </form>' . "\n";
  734.         } // end of show duplicate entry
  735.  
  736.         echo '</div>';
  737.  
  738.         if (!empty($back_url) && $exit) {
  739.             $goto_back_url='<a href="' . (strstr($back_url, '?') ? $back_url . '&no_history=true' : $back_url . '?no_history=true') . '"> ';
  740.             echo '            </td> ' . "\n"
  741.                . '        </tr>' . "\n"
  742.                . '        <tr><td class="tblHeaders" align="center">';
  743.             echo '[' . $goto_back_url . $GLOBALS['strBack'] . ' </a>]';
  744.         }
  745.         echo '            </td>' . "\n"
  746.            . '        </tr>' . "\n"
  747.            . '    </table>' . "\n\n";
  748.         if ($exit) {
  749.             require_once('./footer.inc.php');
  750.         }
  751.     } // end of the 'PMA_mysqlDie()' function
  752.  
  753.  
  754.     /**
  755.      * Defines whether a string exists inside an array or not
  756.      *
  757.      * @param   string   string to search for
  758.      * @param   mixed    array to search into
  759.      *
  760.      * @return  integer  the rank of the $toFind string in the array or '-1' if
  761.      *                   it hasn't been found
  762.      *
  763.      * @access  public
  764.      */
  765.     function PMA_isInto($toFind = '', &$in)
  766.     {
  767.         $max = count($in);
  768.         for ($i = 0; $i < $max && ($toFind != $in[$i]); $i++) {
  769.             // void();
  770.         }
  771.  
  772.         return ($i < $max) ? $i : -1;
  773.     }  // end of the 'PMA_isInto()' function
  774.  
  775.  
  776.     /**
  777.      * Returns a string formatted with CONVERT ... USING
  778.      * if MySQL supports it
  779.      *
  780.      * @param   string  the string itself
  781.      * @param   string  the mode: quoted or unquoted (this one by default)
  782.      *
  783.      * @return  the formatted string
  784.      *
  785.      * @access  private
  786.      */
  787.     function PMA_convert_using($string, $mode='unquoted') {
  788.  
  789.         if ($mode == 'quoted') {
  790.             $possible_quote = "'";
  791.         } else {
  792.             $possible_quote = "";
  793.         }
  794.  
  795.         if (PMA_MYSQL_INT_VERSION >= 40100) {
  796.             list($conn_charset) = explode('_', $GLOBALS['collation_connection']);
  797.             $converted_string = "CONVERT(" . $possible_quote . $string . $possible_quote . " USING " . $conn_charset . ")";
  798.         } else {
  799.             $converted_string = $possible_quote . $string . $possible_quote;
  800.         }
  801.         return $converted_string;
  802.     } // end function
  803.  
  804. }
  805.  
  806. /**
  807.  * Get the complete list of Databases a user can access
  808.  *
  809.  * @param   boolean   whether to include check on failed 'only_db' operations
  810.  * @param   resource  database handle (superuser)
  811.  * @param   integer   amount of databases inside the 'only_db' container
  812.  * @param   resource  possible resource from a failed previous query
  813.  * @param   resource  database handle (user)
  814.  * @param   array     configuration
  815.  * @param   array     previous list of databases
  816.  *
  817.  * @return  array     all databases a user has access to
  818.  *
  819.  * @access  private
  820.  */
  821. function PMA_safe_db_list($only_db_check, $dbh, $dblist_cnt, $rs, $userlink, $cfg, $dblist) {
  822.     if ($only_db_check == FALSE) {
  823.         // try to get the available dbs list
  824.         // use userlink by default
  825.         $dblist = PMA_DBI_get_dblist();
  826.         $dblist_cnt   = count($dblist);
  827.  
  828.         // did not work so check for available databases in the "mysql" db;
  829.         // I don't think we can fall here now...
  830.         if (!$dblist_cnt) {
  831.             $auth_query   = 'SELECT User, Select_priv '
  832.                           . 'FROM mysql.user '
  833.                           . 'WHERE User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\'';
  834.             $rs           = PMA_DBI_try_query($auth_query, $dbh);
  835.         } // end
  836.     }
  837.  
  838.     // Access to "mysql" db allowed and dblist still empty -> gets the
  839.     // usable db list
  840.     if (!$dblist_cnt
  841.         && ($rs && @PMA_DBI_num_rows($rs))) {
  842.         $row = PMA_DBI_fetch_assoc($rs);
  843.         PMA_DBI_free_result($rs);
  844.         // Correction uva 19991215
  845.         // Previous code assumed database "mysql" admin table "db" column
  846.         // "db" contains literal name of user database, and works if so.
  847.         // Mysql usage generally (and uva usage specifically) allows this
  848.         // column to contain regular expressions (we have all databases
  849.         // owned by a given student/faculty/staff beginning with user i.d.
  850.         // and governed by default by a single set of privileges with
  851.         // regular expression as key). This breaks previous code.
  852.         // This maintenance is to fix code to work correctly for regular
  853.         // expressions.
  854.         if ($row['Select_priv'] != 'Y') {
  855.  
  856.             // 1. get allowed dbs from the "mysql.db" table
  857.             // lem9: User can be blank (anonymous user)
  858.             $local_query = 'SELECT DISTINCT Db FROM mysql.db WHERE Select_priv = \'Y\' AND (User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\' OR User = \'\')';
  859.             $rs          = PMA_DBI_try_query($local_query, $dbh);
  860.             if ($rs && @PMA_DBI_num_rows($rs)) {
  861.                 // Will use as associative array of the following 2 code
  862.                 // lines:
  863.                 //   the 1st is the only line intact from before
  864.                 //     correction,
  865.                 //   the 2nd replaces $dblist[] = $row['Db'];
  866.                 $uva_mydbs = array();
  867.                 // Code following those 2 lines in correction continues
  868.                 // populating $dblist[], as previous code did. But it is
  869.                 // now populated with actual database names instead of
  870.                 // with regular expressions.
  871.                 while ($row = PMA_DBI_fetch_assoc($rs)) {
  872.                     // loic1: all databases cases - part 1
  873.                     if (empty($row['Db']) || $row['Db'] == '%') {
  874.                         $uva_mydbs['%'] = 1;
  875.                         break;
  876.                     }
  877.                     // loic1: avoid multiple entries for dbs
  878.                     if (!isset($uva_mydbs[$row['Db']])) {
  879.                         $uva_mydbs[$row['Db']] = 1;
  880.                     }
  881.                 } // end while
  882.                 PMA_DBI_free_result($rs);
  883.                 $uva_alldbs = PMA_DBI_query('SHOW DATABASES;', $GLOBALS['dbh']);
  884.                 // loic1: all databases cases - part 2
  885.                 if (isset($uva_mydbs['%'])) {
  886.                     while ($uva_row = PMA_DBI_fetch_row($uva_alldbs)) {
  887.                         $dblist[] = $uva_row[0];
  888.                     } // end while
  889.                 } // end if
  890.                 else {
  891.                     while ($uva_row = PMA_DBI_fetch_row($uva_alldbs)) {
  892.                         $uva_db = $uva_row[0];
  893.                         if (isset($uva_mydbs[$uva_db]) && $uva_mydbs[$uva_db] == 1) {
  894.                             $dblist[]           = $uva_db;
  895.                             $uva_mydbs[$uva_db] = 0;
  896.                         } else if (!isset($dblist[$uva_db])) {
  897.                             foreach ($uva_mydbs AS $uva_matchpattern => $uva_value) {
  898.                                 // loic1: fixed bad regexp
  899.                                 // TODO: db names may contain characters
  900.                                 //       that are regexp instructions
  901.                                 $re        = '(^|(\\\\\\\\)+|[^\])';
  902.                                 $uva_regex = ereg_replace($re . '%', '\\1.*', ereg_replace($re . '_', '\\1.{1}', $uva_matchpattern));
  903.                                 // Fixed db name matching
  904.                                 // 2000-08-28 -- Benjamin Gandon
  905.                                 if (ereg('^' . $uva_regex . '$', $uva_db)) {
  906.                                     $dblist[] = $uva_db;
  907.                                     break;
  908.                                 }
  909.                             } // end while
  910.                         } // end if ... else if....
  911.                     } // end while
  912.                 } // end else
  913.                 PMA_DBI_free_result($uva_alldbs);
  914.                 unset($uva_mydbs);
  915.             } // end if
  916.  
  917.             // 2. get allowed dbs from the "mysql.tables_priv" table
  918.             $local_query = 'SELECT DISTINCT Db FROM mysql.tables_priv WHERE Table_priv LIKE \'%Select%\' AND User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\'';
  919.             $rs          = PMA_DBI_try_query($local_query, $dbh);
  920.             if ($rs && @PMA_DBI_num_rows($rs)) {
  921.                 while ($row = PMA_DBI_fetch_assoc($rs)) {
  922.                     if (PMA_isInto($row['Db'], $dblist) == -1) {
  923.                         $dblist[] = $row['Db'];
  924.                     }
  925.                 } // end while
  926.                 PMA_DBI_free_result($rs);
  927.             } // end if
  928.         } // end if
  929.     } // end building available dbs from the "mysql" db
  930.  
  931.     return $dblist;
  932. }
  933.  
  934. /**
  935.  * Determines the font sizes to use depending on the os and browser of the
  936.  * user.
  937.  *
  938.  * This function is based on an article from phpBuilder (see
  939.  * http://www.phpbuilder.net/columns/tim20000821.php).
  940.  *
  941.  * @return  boolean    always true
  942.  *
  943.  * @global  string     the standard font size
  944.  * @global  string     the font size for titles
  945.  * @global  string     the small font size
  946.  * @global  string     the smallest font size
  947.  *
  948.  * @access  public
  949.  *
  950.  * @version 1.1
  951.  */
  952. function PMA_setFontSizes()
  953. {
  954.     global $font_size, $font_biggest, $font_bigger, $font_smaller, $font_smallest;
  955.  
  956.     // IE (<7)/Opera (<7) for win case: needs smaller fonts than anyone else
  957.     if (PMA_USR_OS == 'Win'
  958.         && ((PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 7)
  959.         || (PMA_USR_BROWSER_AGENT == 'OPERA' && PMA_USR_BROWSER_VER < 7))) {
  960.         $font_size     = 'x-small';
  961.         $font_biggest  = 'large';
  962.         $font_bigger   = 'medium';
  963.         $font_smaller  = '90%';
  964.         $font_smallest = '7pt';
  965.     }
  966.     // IE6 and other browsers for win case
  967.     else if (PMA_USR_OS == 'Win') {
  968.         $font_size     = 'small';
  969.         $font_biggest  = 'large';
  970.         $font_bigger   = 'medium';
  971.         $font_smaller  = (PMA_USR_BROWSER_AGENT == 'IE')
  972.                         ? '90%'
  973.                         : 'x-small';
  974.         $font_smallest = 'x-small';
  975.     }
  976.     // Some mac browsers need also smaller default fonts size (OmniWeb &
  977.     // Opera)...
  978.     // and a beta version of Safari did also, but not the final 1.0 version
  979.     // so I remove   || PMA_USR_BROWSER_AGENT == 'SAFARI'
  980.     // but we got a report that Safari 1.0 build 85.5 needs it!
  981.  
  982.     else if (PMA_USR_OS == 'Mac'
  983.                 && (PMA_USR_BROWSER_AGENT == 'OMNIWEB' || PMA_USR_BROWSER_AGENT == 'OPERA' || PMA_USR_BROWSER_AGENT == 'SAFARI')) {
  984.         $font_size     = 'x-small';
  985.         $font_biggest  = 'large';
  986.         $font_bigger   = 'medium';
  987.         $font_smaller  = '90%';
  988.         $font_smallest = '7pt';
  989.     }
  990.     // ... but most of them (except IE 5+ & NS 6+) need bigger fonts
  991.     else if ((PMA_USR_OS == 'Mac'
  992.                 && ((PMA_USR_BROWSER_AGENT != 'IE' && PMA_USR_BROWSER_AGENT != 'MOZILLA')
  993.                     || PMA_USR_BROWSER_VER < 5))
  994.             || PMA_USR_BROWSER_AGENT == 'KONQUEROR') {
  995.         $font_size     = 'medium';
  996.         $font_biggest  = 'x-large';
  997.         $font_bigger   = 'large';
  998.         $font_smaller  = 'small';
  999.         $font_smallest = 'x-small';
  1000.     }
  1001.     // OS/2 browser
  1002.     else if (PMA_USR_OS == 'OS/2'
  1003.                 && PMA_USR_BROWSER_AGENT == 'OPERA') {
  1004.         $font_size     = 'small';
  1005.         $font_biggest  = 'medium';
  1006.         $font_bigger   = 'medium';
  1007.         $font_smaller  = 'x-small';
  1008.         $font_smallest = 'x-small';
  1009.     }
  1010.     else {
  1011.         $font_size     = 'small';
  1012.         $font_biggest  = 'large';
  1013.         $font_bigger   = 'medium';
  1014.         $font_smaller  = 'x-small';
  1015.         $font_smallest = 'x-small';
  1016.     }
  1017.  
  1018.     return TRUE;
  1019. } // end of the 'PMA_setFontSizes()' function
  1020.  
  1021.  
  1022. if ($is_minimum_common == FALSE) {
  1023.     /**
  1024.      * $cfg['PmaAbsoluteUri'] is a required directive else cookies won't be
  1025.      * set properly and, depending on browsers, inserting or updating a
  1026.      * record might fail
  1027.      */
  1028.     $display_pmaAbsoluteUri_warning = 0;
  1029.  
  1030.     // Setup a default value to let the people and lazy syadmins work anyway,
  1031.     // but display a big warning on the main.php page.
  1032.     if (empty($cfg['PmaAbsoluteUri'])) {
  1033.  
  1034.         $url = array();
  1035.  
  1036.         // At first we try to parse REQUEST_URI, it might contain full URI
  1037.         if (!empty($_SERVER['REQUEST_URI'])) {
  1038.             $url = parse_url($_SERVER['REQUEST_URI']);
  1039.         }
  1040.  
  1041.         // If we don't have scheme, we didn't have full URL so we need to dig deeper
  1042.         if (empty($url['scheme'])) {
  1043.             // Scheme
  1044.             if (!empty($_SERVER['HTTP_SCHEME'])) {
  1045.                 $url['scheme'] = $_SERVER['HTTP_SCHEME'];
  1046.             } else {
  1047.                 $url['scheme'] = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? 'https' : 'http';
  1048.             }
  1049.  
  1050.             // Host and port
  1051.             if (!empty($_SERVER['HTTP_HOST'])) {
  1052.                 if (strpos($_SERVER['HTTP_HOST'], ':') > 0) {
  1053.                     list($url['host'], $url['port']) = explode(':', $_SERVER['HTTP_HOST']);
  1054.                 } else {
  1055.                     $url['host'] = $_SERVER['HTTP_HOST'];
  1056.                 }
  1057.             } else if (!empty($_SERVER['SERVER_NAME'])) {
  1058.                 $url['host'] = $_SERVER['SERVER_NAME'];
  1059.             } else {
  1060.                 header('Content-Type: text/html; charset=' . $charset);
  1061.                 // Displays the error message
  1062.                 ?>
  1063. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  1064. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  1065. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $available_languages[$lang][2]; ?>" lang="<?php echo $available_languages[$lang][2]; ?>" dir="<?php echo $text_dir; ?>">
  1066.  
  1067. <head>
  1068. <title>phpMyAdmin</title>
  1069. <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $charset; ?>" />
  1070.  
  1071. <style type="text/css">
  1072. <!--
  1073. body  {font-family: sans-serif; font-size: small; color: #000000; background-color: #F5F5F5}
  1074. h1    {font-family: sans-serif; font-size: large; font-weight: bold}
  1075. //-->
  1076. </style>
  1077. </head>
  1078.  
  1079.  
  1080. <body bgcolor="#ffffff">
  1081. <h1>phpMyAdmin - <?php echo $strError; ?></h1>
  1082. <p>
  1083. <?php echo $strPmaUriError; ?><br /><br />
  1084. </p>
  1085. </body>
  1086.  
  1087. </html>
  1088.                 <?php
  1089.                 exit();
  1090.             }
  1091.  
  1092.             // If we didn't set port yet...
  1093.             if (empty($url['port']) && !empty($_SERVER['SERVER_PORT'])) {
  1094.                 $url['port'] = $_SERVER['SERVER_PORT'];
  1095.             }
  1096.  
  1097.             // And finally the path could be already set from REQUEST_URI
  1098.             if (empty($url['path'])) {
  1099.                 if (!empty($_SERVER['PATH_INFO'])) {
  1100.                     $path = parse_url($_SERVER['PATH_INFO']);
  1101.                 } else {
  1102.                     // PHP_SELF in CGI often points to cgi executable, so use it as last choice
  1103.                     $path = parse_url($_SERVER['PHP_SELF']);
  1104.                 }
  1105.                 $url['path'] = $path['path'];
  1106.                 unset($path);
  1107.             }
  1108.         }
  1109.  
  1110.         // Make url from parts we have
  1111.         $cfg['PmaAbsoluteUri'] = $url['scheme'] . '://';
  1112.         // Was there user information?
  1113.         if (!empty($url['user'])) {
  1114.             $cfg['PmaAbsoluteUri'] .= $url['user'];
  1115.             if (!empty($url['pass'])) {
  1116.                 $cfg['PmaAbsoluteUri'] .= ':' . $url['pass'];
  1117.             }
  1118.             $cfg['PmaAbsoluteUri'] .= '@';
  1119.         }
  1120.         // Add hostname
  1121.         $cfg['PmaAbsoluteUri'] .= $url['host'];
  1122.         // Add port, if it not the default one
  1123.         if (!empty($url['port']) && (($url['scheme'] == 'http' && $url['port'] != 80) || ($url['scheme'] == 'https' && $url['port'] != 443))) {
  1124.             $cfg['PmaAbsoluteUri'] .= ':' . $url['port'];
  1125.         }
  1126.         // And finally path, without script name
  1127.         $cfg['PmaAbsoluteUri'] .= substr($url['path'], 0, strrpos($url['path'], '/') + 1);
  1128.  
  1129.         unset($url);
  1130.  
  1131.         // We display the warning by default, but not if it is disabled thru
  1132.         // via the $cfg['PmaAbsoluteUri_DisableWarning'] variable.
  1133.         // This is intended for sysadmins that actually want the default
  1134.         // behaviour of auto-detection due to their setup.
  1135.         // See the mailing list message:
  1136.         // http://sourceforge.net/mailarchive/forum.php?thread_id=859093&forum_id=2141
  1137.         if ($cfg['PmaAbsoluteUri_DisableWarning'] == FALSE) {
  1138.             $display_pmaAbsoluteUri_warning = 1;
  1139.         }
  1140.     } else {
  1141.         // The URI is specified, however users do often specify this
  1142.         // wrongly, so we try to fix this.
  1143.  
  1144.         // Adds a trailing slash et the end of the phpMyAdmin uri if it
  1145.         // does not exist.
  1146.         if (substr($cfg['PmaAbsoluteUri'], -1) != '/') {
  1147.             $cfg['PmaAbsoluteUri'] .= '/';
  1148.         }
  1149.  
  1150.         // If URI doesn't start with http:// or https://, we will add
  1151.         // this.
  1152.         if (substr($cfg['PmaAbsoluteUri'], 0, 7) != 'http://' && substr($cfg['PmaAbsoluteUri'], 0, 8) != 'https://') {
  1153.             $cfg['PmaAbsoluteUri']          = ((!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? 'https' : 'http') . ':'
  1154.                                             . (substr($cfg['PmaAbsoluteUri'], 0, 2) == '//' ? '' : '//')
  1155.                                             . $cfg['PmaAbsoluteUri'];
  1156.         }
  1157.     }
  1158.  
  1159.     // some variables used mostly for cookies:
  1160.     $pma_uri_parts = parse_url($cfg['PmaAbsoluteUri']);
  1161.     $cookie_path   = substr($pma_uri_parts['path'], 0, strrpos($pma_uri_parts['path'], '/')) . '/';
  1162.     $is_https      = (isset($pma_uri_parts['scheme']) && $pma_uri_parts['scheme'] == 'https') ? 1 : 0;
  1163.  
  1164.     $dblist       = array();
  1165.  
  1166.     /**
  1167.      * Gets the valid servers list and parameters
  1168.      */
  1169.     foreach ($cfg['Servers'] AS $key => $val) {
  1170.         // Don't use servers with no hostname
  1171.         if ( ($val['connect_type'] == 'tcp') && empty($val['host'])) {
  1172.             unset($cfg['Servers'][$key]);
  1173.         }
  1174.  
  1175.         // Final solution to bug #582890
  1176.         // If we are using a socket connection
  1177.         // and there is nothing in the verbose server name
  1178.         // or the host field, then generate a name for the server
  1179.         // in the form of "Server 2", localized of course!
  1180.         if ( ($val['connect_type'] == 'socket') && empty($val['host']) && empty($val['verbose']) ) {
  1181.             $cfg['Servers'][$key]['verbose'] = $GLOBALS['strServer'] . $key;
  1182.             $val['verbose']                  = $GLOBALS['strServer'] . $key;
  1183.         }
  1184.     }
  1185.  
  1186.     if (empty($server) || !isset($cfg['Servers'][$server]) || !is_array($cfg['Servers'][$server])) {
  1187.         $server = $cfg['ServerDefault'];
  1188.     }
  1189.  
  1190.  
  1191.     /**
  1192.      * If no server is selected, make sure that $cfg['Server'] is empty (so
  1193.      * that nothing will work), and skip server authentication.
  1194.      * We do NOT exit here, but continue on without logging into any server.
  1195.      * This way, the welcome page will still come up (with no server info) and
  1196.      * present a choice of servers in the case that there are multiple servers
  1197.      * and '$cfg['ServerDefault'] = 0' is set.
  1198.      */
  1199.     if ($server == 0) {
  1200.         $cfg['Server'] = array();
  1201.     }
  1202.  
  1203.     /**
  1204.      * Otherwise, set up $cfg['Server'] and do the usual login stuff.
  1205.      */
  1206.     else if (isset($cfg['Servers'][$server])) {
  1207.         $cfg['Server'] = $cfg['Servers'][$server];
  1208.  
  1209.         /**
  1210.          * Loads the proper database interface for this server
  1211.          */
  1212.         require_once('./libraries/database_interface.lib.php');
  1213.  
  1214.         // Gets the authentication library that fits the $cfg['Server'] settings
  1215.         // and run authentication
  1216.  
  1217.         // (for a quick check of path disclosure in auth/cookies:)
  1218.         $coming_from_common = TRUE;
  1219.  
  1220.         require_once('./libraries/auth/' . $cfg['Server']['auth_type'] . '.auth.lib.php');
  1221.         if (!PMA_auth_check()) {
  1222.             PMA_auth();
  1223.         } else {
  1224.             PMA_auth_set_user();
  1225.         }
  1226.  
  1227.         // Check IP-based Allow/Deny rules as soon as possible to reject the
  1228.         // user
  1229.         // Based on mod_access in Apache:
  1230.         // http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/aaa/mod_access.c?rev=1.37&content-type=text/vnd.viewcvs-markup
  1231.         // Look at: "static int check_dir_access(request_rec *r)"
  1232.         // Robbat2 - May 10, 2002
  1233.         if (isset($cfg['Server']['AllowDeny']) && isset($cfg['Server']['AllowDeny']['order'])) {
  1234.             require_once('./libraries/ip_allow_deny.lib.php');
  1235.  
  1236.             $allowDeny_forbidden         = FALSE; // default
  1237.             if ($cfg['Server']['AllowDeny']['order'] == 'allow,deny') {
  1238.                 $allowDeny_forbidden     = TRUE;
  1239.                 if (PMA_allowDeny('allow')) {
  1240.                     $allowDeny_forbidden = FALSE;
  1241.                 }
  1242.                 if (PMA_allowDeny('deny')) {
  1243.                     $allowDeny_forbidden = TRUE;
  1244.                 }
  1245.             } else if ($cfg['Server']['AllowDeny']['order'] == 'deny,allow') {
  1246.                 if (PMA_allowDeny('deny')) {
  1247.                     $allowDeny_forbidden = TRUE;
  1248.                 }
  1249.                 if (PMA_allowDeny('allow')) {
  1250.                     $allowDeny_forbidden = FALSE;
  1251.                 }
  1252.             } else if ($cfg['Server']['AllowDeny']['order'] == 'explicit') {
  1253.                 if (PMA_allowDeny('allow')
  1254.                     && !PMA_allowDeny('deny')) {
  1255.                     $allowDeny_forbidden = FALSE;
  1256.                 } else {
  1257.                     $allowDeny_forbidden = TRUE;
  1258.                 }
  1259.             } // end if... else if... else if
  1260.  
  1261.             // Ejects the user if banished
  1262.             if ($allowDeny_forbidden) {
  1263.                PMA_auth_fails();
  1264.             }
  1265.             unset($allowDeny_forbidden); //Clean up after you!
  1266.         } // end if
  1267.  
  1268.         // is root allowed?
  1269.         if (!$cfg['Server']['AllowRoot'] && $cfg['Server']['user'] == 'root') {
  1270.             $allowDeny_forbidden = TRUE;
  1271.             PMA_auth_fails();
  1272.             unset($allowDeny_forbidden); //Clean up after you!
  1273.         }
  1274.  
  1275.         // The user can work with only some databases
  1276.         if (isset($cfg['Server']['only_db']) && $cfg['Server']['only_db'] != '') {
  1277.             if (is_array($cfg['Server']['only_db'])) {
  1278.                 $dblist   = $cfg['Server']['only_db'];
  1279.             } else {
  1280.                 $dblist[] = $cfg['Server']['only_db'];
  1281.             }
  1282.         } // end if
  1283.  
  1284.         $bkp_track_err = @ini_set('track_errors', 1);
  1285.  
  1286.         // Try to connect MySQL with the control user profile (will be used to
  1287.         // get the privileges list for the current user but the true user link
  1288.         // must be open after this one so it would be default one for all the
  1289.         // scripts)
  1290.         if ($cfg['Server']['controluser'] != '') {
  1291.             $dbh = PMA_DBI_connect($cfg['Server']['controluser'], $cfg['Server']['controlpass'], TRUE);
  1292.         } else {
  1293.             $dbh = PMA_DBI_connect($cfg['Server']['user'], $cfg['Server']['password'], TRUE);
  1294.         } // end if ... else
  1295.  
  1296.         // Pass #1 of DB-Config to read in master level DB-Config will go here
  1297.         // Robbat2 - May 11, 2002
  1298.  
  1299.         // Connects to the server (validates user's login)
  1300.         $userlink = PMA_DBI_connect($cfg['Server']['user'], $cfg['Server']['password'], FALSE);
  1301.  
  1302.         // Pass #2 of DB-Config to read in user level DB-Config will go here
  1303.         // Robbat2 - May 11, 2002
  1304.  
  1305.         @ini_set('track_errors', $bkp_track_err);
  1306.         unset($bkp_track_err);
  1307.  
  1308.         /**
  1309.          * SQL Parser code
  1310.          */
  1311.         require_once('./libraries/sqlparser.lib.php');
  1312.  
  1313.         /**
  1314.          * SQL Validator interface code
  1315.          */
  1316.         require_once('./libraries/sqlvalidator.lib.php');
  1317.  
  1318.         // if 'only_db' is set for the current user, there is no need to check for
  1319.         // available databases in the "mysql" db
  1320.         $dblist_cnt = count($dblist);
  1321.         if ($dblist_cnt) {
  1322.             $true_dblist  = array();
  1323.             $is_show_dbs  = TRUE;
  1324.  
  1325.             $dblist_asterisk_bool = FALSE;
  1326.             for ($i = 0; $i < $dblist_cnt; $i++) {
  1327.  
  1328.                 // The current position
  1329.                 if ($dblist[$i] == '*' && $dblist_asterisk_bool == FALSE) {
  1330.                     $dblist_asterisk_bool = TRUE;
  1331.                     $dblist_full = PMA_safe_db_list(FALSE, $dbh, FALSE, $rs, $userlink, $cfg, $dblist);
  1332.                     foreach ($dblist_full AS $dbl_key => $dbl_val) {
  1333.                         if (!in_array($dbl_val, $dblist)) {
  1334.                             $true_dblist[] = $dbl_val;
  1335.                         }
  1336.                     }
  1337.  
  1338.                     continue;
  1339.                 } elseif ($dblist[$i] == '*') {
  1340.                     // We don't want more than one asterisk inside our 'only_db'.
  1341.                     continue;
  1342.                 }
  1343.                 if ($is_show_dbs && ereg('(^|[^\])(_|%)', $dblist[$i])) {
  1344.                     $local_query = 'SHOW DATABASES LIKE \'' . $dblist[$i] . '\'';
  1345.                     // here, a PMA_DBI_query() could fail silently
  1346.                     // if SHOW DATABASES is disabled
  1347.                     $rs          = PMA_DBI_try_query($local_query, $dbh);
  1348.  
  1349.                     if ($i == 0
  1350.                         && (substr(PMA_DBI_getError($dbh), 1, 4) == 1045)) {
  1351.                         // "SHOW DATABASES" statement is disabled
  1352.                         $true_dblist[] = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i]));
  1353.                         $is_show_dbs   = FALSE;
  1354.                     }
  1355.                     // Debug
  1356.                     // else if (PMA_DBI_getError($dbh)) {
  1357.                     //    PMA_mysqlDie(PMA_DBI_getError($dbh), $local_query, FALSE);
  1358.                     // }
  1359.                     while ($row = @PMA_DBI_fetch_row($rs)) {
  1360.                         $true_dblist[] = $row[0];
  1361.                     } // end while
  1362.                     if ($rs) {
  1363.                         PMA_DBI_free_result($rs);
  1364.                     }
  1365.                 } else {
  1366.                     $true_dblist[]     = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i]));
  1367.                 } // end if... else...
  1368.             } // end for
  1369.             $dblist       = $true_dblist;
  1370.             unset($true_dblist);
  1371.             $only_db_check = TRUE;
  1372.         } // end if
  1373.  
  1374.         // 'only_db' is empty for the current user...
  1375.         else {
  1376.             $only_db_check = FALSE;
  1377.         } // end if (!$dblist_cnt)
  1378.  
  1379.         if (isset($dblist_full) && !count($dblist_full)) {
  1380.             $dblist = PMA_safe_db_list($only_db_check, $dbh, $dblist_cnt, $rs, $userlink, $cfg, $dblist);
  1381.         }
  1382.  
  1383.     } // end server connecting
  1384.     /**
  1385.      * Missing server hostname
  1386.      */
  1387.     else {
  1388.         echo $strHostEmpty;
  1389.     }
  1390.  
  1391.     /**
  1392.      * Send HTTP header, taking IIS limits into account
  1393.      *                   ( 600 seems ok)
  1394.      *
  1395.      * @param   string   the header to send
  1396.      *
  1397.      * @return  boolean  always true
  1398.      */
  1399.      function PMA_sendHeaderLocation($uri)
  1400.      {
  1401.          if (PMA_IS_IIS && strlen($uri) > 600) {
  1402.  
  1403.              echo '<html><head><title>- - -</title>' . "\n";
  1404.              echo '<meta http-equiv="expires" content="0">' . "\n";
  1405.              echo '<meta http-equiv="Pragma" content="no-cache">' . "\n";
  1406.              echo '<meta http-equiv="Cache-Control" content="no-cache">' . "\n";
  1407.              echo '<meta http-equiv="Refresh" content="0;url=' .$uri . '">' . "\n";
  1408.              echo '<script language="JavaScript">' . "\n";
  1409.              echo 'setTimeout ("window.location = unescape(\'"' . $uri . '"\')",2000); </script>' . "\n";
  1410.              echo '</head>' . "\n";
  1411.              echo '<body> <script language="JavaScript">' . "\n";
  1412.              echo 'document.write (\'<p><a href="' . $uri . '">' . $GLOBALS['strGo'] . '</a></p>\');' . "\n";
  1413.              echo '</script></body></html>' . "\n";
  1414.  
  1415.          } else {
  1416.              header('Location: ' . $uri);
  1417.          }
  1418.      }
  1419.  
  1420.  
  1421.     /**
  1422.      * Get the list and number of available databases.
  1423.      *
  1424.      * @param   string   the url to go back to in case of error
  1425.      *
  1426.      * @return  boolean  always true
  1427.      *
  1428.      * @global  array    the list of available databases
  1429.      * @global  integer  the number of available databases
  1430.      * @global  array    current configuration
  1431.      */
  1432.     function PMA_availableDatabases($error_url = '')
  1433.     {
  1434.         global $dblist;
  1435.         global $num_dbs;
  1436.         global $cfg;
  1437.  
  1438.         $num_dbs = count($dblist);
  1439.  
  1440.         // 1. A list of allowed databases has already been defined by the
  1441.         //    authentification process -> gets the available databases list
  1442.         if ($num_dbs) {
  1443.             $true_dblist = array();
  1444.             for ($i = 0; $i < $num_dbs; $i++) {
  1445.                 $dblink  = @PMA_DBI_select_db($dblist[$i]);
  1446.                 if ($dblink) {
  1447.                     $true_dblist[] = $dblist[$i];
  1448.                 } // end if
  1449.             } // end for
  1450.             $dblist      = array();
  1451.             $dblist      = $true_dblist;
  1452.             unset($true_dblist);
  1453.             $num_dbs     = count($dblist);
  1454.         } // end if
  1455.         // 2. Allowed database list is empty -> gets the list of all databases
  1456.         //    on the server
  1457.         else if (!isset($cfg['Server']['only_db']) || $cfg['Server']['only_db'] == '') {
  1458.             $dblist = PMA_DBI_get_dblist(); // needed? or PMA_mysqlDie('', 'SHOW DATABASES;', FALSE, $error_url);
  1459.             $num_dbs = count($dblist);
  1460.         } // end else
  1461.  
  1462.         return TRUE;
  1463.     } // end of the 'PMA_availableDatabases()' function
  1464.  
  1465.  
  1466.  
  1467.     /* ----------------------- Set of misc functions ----------------------- */
  1468.  
  1469.  
  1470.     /**
  1471.      * Adds backquotes on both sides of a database, table or field name.
  1472.      * Since MySQL 3.23.6 this allows to use non-alphanumeric characters in
  1473.      * these names.
  1474.      *
  1475.      * @param   mixed    the database, table or field name to "backquote" or
  1476.      *                   array of it
  1477.      * @param   boolean  a flag to bypass this function (used by dump
  1478.      *                   functions)
  1479.      *
  1480.      * @return  mixed    the "backquoted" database, table or field name if the
  1481.      *                   current MySQL release is >= 3.23.6, the original one
  1482.      *                   else
  1483.      *
  1484.      * @access  public
  1485.      */
  1486.     function PMA_backquote($a_name, $do_it = TRUE)
  1487.     {
  1488.         // '0' is also empty for php :-(
  1489.         if ($do_it
  1490.             && (!empty($a_name) || $a_name == '0') && $a_name != '*') {
  1491.  
  1492.             if (is_array($a_name)) {
  1493.                  $result = array();
  1494.                  foreach ($a_name AS $key => $val) {
  1495.                      $result[$key] = '`' . $val . '`';
  1496.                  }
  1497.                  return $result;
  1498.             } else {
  1499.                 return '`' . $a_name . '`';
  1500.             }
  1501.         } else {
  1502.             return $a_name;
  1503.         }
  1504.     } // end of the 'PMA_backquote()' function
  1505.  
  1506.  
  1507.     /**
  1508.      * Format a string so it can be passed to a javascript function.
  1509.      * This function is used to displays a javascript confirmation box for
  1510.      * "DROP/DELETE/ALTER" queries.
  1511.      *
  1512.      * @param   string   the string to format
  1513.      * @param   boolean  whether to add backquotes to the string or not
  1514.      *
  1515.      * @return  string   the formated string
  1516.      *
  1517.      * @access  public
  1518.      */
  1519.     function PMA_jsFormat($a_string = '', $add_backquotes = TRUE)
  1520.     {
  1521.         if (is_string($a_string)) {
  1522.             $a_string = htmlspecialchars($a_string);
  1523.             $a_string = str_replace('\\', '\\\\', $a_string);
  1524.             $a_string = str_replace('\'', '\\\'', $a_string);
  1525.             $a_string = str_replace('#', '\\#', $a_string);
  1526.             $a_string = str_replace("\012", '\\\\n', $a_string);
  1527.             $a_string = str_replace("\015", '\\\\r', $a_string);
  1528.         }
  1529.  
  1530.         return (($add_backquotes) ? PMA_backquote($a_string) : $a_string);
  1531.     } // end of the 'PMA_jsFormat()' function
  1532.  
  1533.  
  1534.     /**
  1535.      * Defines the <CR><LF> value depending on the user OS.
  1536.      *
  1537.      * @return  string   the <CR><LF> value to use
  1538.      *
  1539.      * @access  public
  1540.      */
  1541.     function PMA_whichCrlf()
  1542.     {
  1543.         $the_crlf = "\n";
  1544.  
  1545.         // The 'PMA_USR_OS' constant is defined in "./libraries/defines.lib.php"
  1546.         // Win case
  1547.         if (PMA_USR_OS == 'Win') {
  1548.             $the_crlf = "\r\n";
  1549.         }
  1550.         // Mac case
  1551.         else if (PMA_USR_OS == 'Mac') {
  1552.             $the_crlf = "\r";
  1553.         }
  1554.         // Others
  1555.         else {
  1556.             $the_crlf = "\n";
  1557.         }
  1558.  
  1559.         return $the_crlf;
  1560.     } // end of the 'PMA_whichCrlf()' function
  1561.  
  1562.  
  1563.     /**
  1564.      * Counts and displays the number of records in a table
  1565.      *
  1566.      * Last revision 13 July 2001: Patch for limiting dump size from
  1567.      * vinay@sanisoft.com & girish@sanisoft.com
  1568.      *
  1569.      * @param   string   the current database name
  1570.      * @param   string   the current table name
  1571.      * @param   boolean  whether to retain or to displays the result
  1572.      * @param   boolean  whether to force an exact count
  1573.      *
  1574.      * @return  mixed    the number of records if retain is required, true else
  1575.      *
  1576.      * @access  public
  1577.      */
  1578.     function PMA_countRecords($db, $table, $ret = FALSE, $force_exact = FALSE)
  1579.     {
  1580.         global $err_url, $cfg;
  1581.         if (!$force_exact) {
  1582.             $result       = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . PMA_sqlAddslashes($table, TRUE) . '\';');
  1583.             $showtable    = PMA_DBI_fetch_assoc($result);
  1584.             $num     = (isset($showtable['Rows']) ? $showtable['Rows'] : 0);
  1585.             if ($num < $cfg['MaxExactCount']) {
  1586.                 unset($num);
  1587.             }
  1588.             PMA_DBI_free_result($result);
  1589.         }
  1590.  
  1591.         if (!isset($num)) {
  1592.             $result    = PMA_DBI_query('SELECT COUNT(*) AS num FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table));
  1593.             list($num) = ($result) ? PMA_DBI_fetch_row($result) : array(0);
  1594.             PMA_DBI_free_result($result);
  1595.         }
  1596.         if ($ret) {
  1597.             return $num;
  1598.         } else {
  1599.             echo number_format($num, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
  1600.             return TRUE;
  1601.         }
  1602.     } // end of the 'PMA_countRecords()' function
  1603.  
  1604.     /**
  1605.      * Reloads navigation if needed.
  1606.      *
  1607.      * @global  mixed   configuration
  1608.      * @global  bool    whether to reload
  1609.      *
  1610.      * @access  public
  1611.      */
  1612.     function PMA_reloadNavigation() {
  1613.         global $cfg;
  1614.  
  1615.         // Reloads the navigation frame via JavaScript if required
  1616.         if (isset($GLOBALS['reload']) && $GLOBALS['reload']) {
  1617.             echo "\n";
  1618.             $reload_url = './left.php?' . PMA_generate_common_url((isset($GLOBALS['db']) ? $GLOBALS['db'] : ''), '', '&');
  1619.             ?>
  1620. <script type="text/javascript" language="javascript1.2">
  1621. <!--
  1622. if (typeof(window.parent) != 'undefined'
  1623.     && typeof(window.parent.frames['nav']) != 'undefined') {
  1624.     window.parent.frames['nav'].goTo('<?php echo $reload_url; ?>&hash=' + <?php echo (($cfg['QueryFrame'] && $cfg['QueryFrameJS']) ? 'window.parent.frames[\'queryframe\'].document.hashform.hash.value' : "'" . md5($cfg['PmaAbsoluteUri']) . "'"); ?>);
  1625. }
  1626. //-->
  1627. </script>
  1628.             <?php
  1629.             unset($GLOBALS['reload']);
  1630.         }
  1631.     }
  1632.  
  1633.     /**
  1634.      * Displays a message at the top of the "main" (right) frame
  1635.      *
  1636.      * @param   string  the message to display
  1637.      *
  1638.      * @global  array   the configuration array
  1639.      *
  1640.      * @access  public
  1641.      */
  1642.     function PMA_showMessage($message)
  1643.     {
  1644.         global $cfg;
  1645.  
  1646.         // Sanitizes $message
  1647.         $message = PMA_sanitize($message);
  1648.  
  1649.         // Corrects the tooltip text via JS if required
  1650.         if (!empty($GLOBALS['table']) && $cfg['ShowTooltip']) {
  1651.             $result = PMA_DBI_try_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], TRUE) . '\'');
  1652.             if ($result) {
  1653.                 $tbl_status = PMA_DBI_fetch_assoc($result);
  1654.                 $tooltip    = (empty($tbl_status['Comment']))
  1655.                             ? ''
  1656.                             : $tbl_status['Comment'] . ' ';
  1657.                 $tooltip .= '(' . $tbl_status['Rows'] . ' ' . $GLOBALS['strRows'] . ')';
  1658.                 PMA_DBI_free_result($result);
  1659.                 $md5_tbl = md5($GLOBALS['table']);
  1660.                 echo "\n";
  1661.                 ?>
  1662. <script type="text/javascript" language="javascript1.2">
  1663. <!--
  1664. if (typeof(document.getElementById) != 'undefined'
  1665.     && typeof(window.parent.frames['nav']) != 'undefined'
  1666.     && typeof(window.parent.frames['nav'].document) != 'undefined' && typeof(window.parent.frames['nav'].document) != 'unknown'
  1667.     && (window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>'))
  1668.     && typeof(window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>')) != 'undefined'
  1669.     && typeof(window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>').title) == 'string') {
  1670.     window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>').title = '<?php echo PMA_jsFormat($tooltip, FALSE); ?>';
  1671. }
  1672. //-->
  1673. </script>
  1674.                 <?php
  1675.             } // end if
  1676.         } // end if... else if
  1677.  
  1678.         // Checks if the table needs to be repaired after a TRUNCATE query.
  1679.         if (isset($GLOBALS['table']) && isset($GLOBALS['sql_query'])
  1680.             && $GLOBALS['sql_query'] == 'TRUNCATE TABLE ' . PMA_backquote($GLOBALS['table'])) {
  1681.             if (!isset($tbl_status)) {
  1682.                 $result = @PMA_DBI_try_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], TRUE) . '\'');
  1683.                 if ($result) {
  1684.                     $tbl_status = PMA_DBI_fetch_assoc($result);
  1685.                     PMA_DBI_free_result($result);
  1686.                 }
  1687.             }
  1688.             if (isset($tbl_status) && (int) $tbl_status['Index_length'] > 1024) {
  1689.                 PMA_DBI_try_query('REPAIR TABLE ' . PMA_backquote($GLOBALS['table']));
  1690.             }
  1691.         }
  1692.         unset($tbl_status);
  1693.  
  1694.         echo "\n";
  1695.         ?>
  1696. <br />
  1697. <div align="<?php echo $GLOBALS['cell_align_left']; ?>">
  1698.     <table border="<?php echo $cfg['Border']; ?>" cellpadding="5" cellspacing="1">
  1699.     <tr>
  1700.         <th<?php echo ($GLOBALS['theme'] != 'original') ? ' class="tblHeaders"' : ' bgcolor="' . $cfg['ThBgcolor'] . '"'; ?>>
  1701.             <b><?php echo $message; ?></b>
  1702.         </th>
  1703.     </tr>
  1704.         <?php
  1705.         if ($cfg['ShowSQL'] == TRUE && (!empty($GLOBALS['sql_query']) || !empty($GLOBALS['display_query']))) {
  1706.             $local_query = !empty($GLOBALS['display_query']) ? $GLOBALS['display_query'] : (($cfg['SQP']['fmtType'] == 'none' && isset($GLOBALS['unparsed_sql']) && $GLOBALS['unparsed_sql'] != '') ? $GLOBALS['unparsed_sql'] : $GLOBALS['sql_query']);
  1707.             // Basic url query part
  1708.             $url_qpart = '?' . PMA_generate_common_url(isset($GLOBALS['db']) ? $GLOBALS['db'] : '', isset($GLOBALS['table']) ? $GLOBALS['table'] : '');
  1709.             echo "\n";
  1710.             ?>
  1711.     <tr>
  1712.         <td bgcolor="<?php echo $cfg['BgcolorOne']; ?>">
  1713.             <?php
  1714.             echo "\n";
  1715.             // Html format the query to be displayed
  1716.             // The nl2br function isn't used because its result isn't a valid
  1717.             // xhtml1.0 statement before php4.0.5 ("<br>" and not "<br />")
  1718.             // If we want to show some sql code it is easiest to create it here
  1719.              /* SQL-Parser-Analyzer */
  1720.             $sqlnr = 1;
  1721.             if (!empty($GLOBALS['show_as_php'])) {
  1722.                 $new_line = '\'<br />' . "\n" . '        . \' ';
  1723.             }
  1724.             if (isset($new_line)) {
  1725.                  /* SQL-Parser-Analyzer */
  1726.                 $query_base = PMA_sqlAddslashes(htmlspecialchars($local_query));
  1727.                  /* SQL-Parser-Analyzer */
  1728.                 $query_base = preg_replace("@((\015\012)|(\015)|(\012))+@", $new_line, $query_base);
  1729.             } else {
  1730.                 $query_base = $local_query;
  1731.             }
  1732.  
  1733.             // Here we append the LIMIT added for navigation, to
  1734.             // enable its display. Adding it higher in the code
  1735.             // to $local_query would create a problem when
  1736.             // using the Refresh or Edit links.
  1737.  
  1738.             // Only append it on SELECTs.
  1739.  
  1740.             // FIXME: what would be the best to do when someone
  1741.             // hits Refresh: use the current LIMITs ?
  1742.  
  1743.             // TODO: use the parser instead of preg_match()
  1744.  
  1745.             if (preg_match('@^SELECT[[:space:]]+@i', $query_base)
  1746.              && isset($GLOBALS['sql_limit_to_append'])) {
  1747.                 $query_base .= $GLOBALS['sql_limit_to_append'];
  1748.             }
  1749.  
  1750.             if (!empty($GLOBALS['show_as_php'])) {
  1751.                 $query_base = '$sql  = \'' . $query_base;
  1752.             } else if (!empty($GLOBALS['validatequery'])) {
  1753.                 $query_base = PMA_validateSQL($query_base);
  1754.             } else {
  1755.                 // avoid reparsing query:
  1756.                 if (isset($GLOBALS['parsed_sql']) && $query_base == $GLOBALS['parsed_sql']['raw']) {
  1757.                     $parsed_sql = $GLOBALS['parsed_sql'];
  1758.                 } else {
  1759.                     $parsed_sql = PMA_SQP_parse($query_base);
  1760.                 }
  1761.                 $query_base = PMA_formatSql($parsed_sql, $query_base);
  1762.             }
  1763.  
  1764.             // Prepares links that may be displayed to edit/explain the query
  1765.             // (don't go to default pages, we must go to the page
  1766.             // where the query box is available)
  1767.             // (also, I don't see why we should check the goto variable)
  1768.  
  1769.             //if (!isset($GLOBALS['goto'])) {
  1770.                 //$edit_target = (isset($GLOBALS['table'])) ? $cfg['DefaultTabTable'] : $cfg['DefaultTabDatabase'];
  1771.             $edit_target = isset($GLOBALS['db']) ? (isset($GLOBALS['table']) ? 'tbl_properties.php' : 'db_details.php') : '';
  1772.             //} else if ($GLOBALS['goto'] != 'main.php') {
  1773.             //    $edit_target = $GLOBALS['goto'];
  1774.             //} else {
  1775.             //    $edit_target = '';
  1776.             //}
  1777.  
  1778.             if (isset($cfg['SQLQuery']['Edit'])
  1779.                 && ($cfg['SQLQuery']['Edit'] == TRUE )
  1780.                 && (!empty($edit_target))) {
  1781.  
  1782.                 $onclick = '';
  1783.                 if ($cfg['QueryFrameJS'] && $cfg['QueryFrame']) {
  1784.                     $onclick = 'onclick="focus_querywindow(\'' . urlencode($local_query) . '\'); return false;"';
  1785.                 }
  1786.  
  1787.                 $edit_link = ' [<a href="'
  1788.                            . $edit_target
  1789.                            . $url_qpart
  1790.                            . '&sql_query=' . urlencode($local_query) . '&show_query=1#querybox" ' . $onclick . '>' . $GLOBALS['strEdit'] . '</a>]';
  1791.             } else {
  1792.                 $edit_link = '';
  1793.             }
  1794.  
  1795.             // Want to have the query explained (Mike Beck 2002-05-22)
  1796.             // but only explain a SELECT (that has not been explained)
  1797.             /* SQL-Parser-Analyzer */
  1798.             if (isset($cfg['SQLQuery']['Explain'])
  1799.                 && $cfg['SQLQuery']['Explain'] == TRUE) {
  1800.  
  1801.                 // Detect if we are validating as well
  1802.                 // To preserve the validate uRL data
  1803.                 if (!empty($GLOBALS['validatequery'])) {
  1804.                     $explain_link_validate = '&validatequery=1';
  1805.                 } else {
  1806.                     $explain_link_validate = '';
  1807.                 }
  1808.  
  1809.                 $explain_link = ' [<a href="read_dump.php'
  1810.                               . $url_qpart
  1811.                               . $explain_link_validate
  1812.                               . '&sql_query=';
  1813.  
  1814.                 if (preg_match('@^SELECT[[:space:]]+@i', $local_query)) {
  1815.                     $explain_link .= urlencode('EXPLAIN ' . $local_query) . '">' . $GLOBALS['strExplain'];
  1816.                 } else if (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $local_query)) {
  1817.                     $explain_link .= urlencode(substr($local_query, 8)) . '">' . $GLOBALS['strNoExplain'];
  1818.                 } else {
  1819.                     $explain_link = '';
  1820.                 }
  1821.                 if (!empty($explain_link)) {
  1822.                     $explain_link .= '</a>]';
  1823.                 }
  1824.             } else {
  1825.                 $explain_link = '';
  1826.             } //show explain
  1827.  
  1828.             // Also we would like to get the SQL formed in some nice
  1829.             // php-code (Mike Beck 2002-05-22)
  1830.             if (isset($cfg['SQLQuery']['ShowAsPHP'])
  1831.                 && $cfg['SQLQuery']['ShowAsPHP'] == TRUE) {
  1832.                 $php_link = ' [<a href="read_dump.php'
  1833.                           . $url_qpart
  1834.                           . '&show_query=1'
  1835.                           . '&sql_query=' . urlencode($local_query)
  1836.                           . '&show_as_php=';
  1837.  
  1838.                 if (!empty($GLOBALS['show_as_php'])) {
  1839.                     $php_link .= '0">' . $GLOBALS['strNoPhp'];
  1840.                 } else {
  1841.                     $php_link .= '1">' . $GLOBALS['strPhp'];
  1842.                 }
  1843.                 $php_link .= '</a>]';
  1844.  
  1845.                 if (isset($GLOBALS['show_as_php']) && $GLOBALS['show_as_php'] == '1') {
  1846.                     $php_link .= ' [<a href="read_dump.php'
  1847.                               . $url_qpart
  1848.                               . '&show_query=1'
  1849.                               . '&sql_query=' . urlencode($local_query)
  1850.                               . '">' . $GLOBALS['strRunQuery'] . '</a>]';
  1851.                 }
  1852.  
  1853.             } else {
  1854.                 $php_link = '';
  1855.             } //show as php
  1856.  
  1857.             // Refresh query
  1858.             if (isset($cfg['SQLQuery']['Refresh'])
  1859.                 && $cfg['SQLQuery']['Refresh']
  1860.                 && preg_match('@^(SELECT|SHOW)[[:space:]]+@i', $local_query)) {
  1861.  
  1862.                 $refresh_link = ' [<a href="read_dump.php'
  1863.                           . $url_qpart
  1864.                           . '&show_query=1'
  1865.                           . '&sql_query=' . urlencode($local_query)
  1866.                           . '">';
  1867.                 $refresh_link .= $GLOBALS['strRefresh'];
  1868.                 $refresh_link .= '</a>]';
  1869.             } else {
  1870.                 $refresh_link = '';
  1871.             } //show as php
  1872.  
  1873.             if (isset($cfg['SQLValidator']['use'])
  1874.                 && $cfg['SQLValidator']['use'] == TRUE
  1875.                 && isset($cfg['SQLQuery']['Validate'])
  1876.                 && $cfg['SQLQuery']['Validate'] == TRUE) {
  1877.                 $validate_link = ' [<a href="read_dump.php'
  1878.                                . $url_qpart
  1879.                                . '&show_query=1'
  1880.                                . '&sql_query=' . urlencode($local_query)
  1881.                                . '&validatequery=';
  1882.                 if (!empty($GLOBALS['validatequery'])) {
  1883.                     $validate_link .= '0">' .  $GLOBALS['strNoValidateSQL'] ;
  1884.                 } else {
  1885.                     $validate_link .= '1">'. $GLOBALS['strValidateSQL'] ;
  1886.                 }
  1887.                 $validate_link .= '</a>]';
  1888.             } else {
  1889.                 $validate_link = '';
  1890.             } //validator
  1891.  
  1892.             // Displays the message
  1893.             echo '            <b>' . $GLOBALS['strSQLQuery'] . ':</b> ';
  1894.             echo '<br />' . "\n";
  1895.             echo '            ' . $query_base;
  1896.  
  1897.             unset($local_query);
  1898.             //Clean up the end of the PHP
  1899.             if (!empty($GLOBALS['show_as_php'])) {
  1900.                 echo '\';';
  1901.             }
  1902.             echo "\n";
  1903.             ?>
  1904.         </td>
  1905.     </tr>
  1906.     <?php
  1907.             if (!empty($edit_target)) {
  1908.                 echo '<tr><td bgcolor="' . $cfg['BgcolorOne'] . '" align="center">';
  1909.                 echo $edit_link . $explain_link . $php_link . $refresh_link . $validate_link;
  1910.                 echo '</td></tr>' . "\n";
  1911.             }
  1912.         }
  1913.         echo "\n";
  1914.         ?>
  1915.     </table>
  1916. </div><br />
  1917.         <?php
  1918.     } // end of the 'PMA_showMessage()' function
  1919.  
  1920.  
  1921.     /**
  1922.      * Formats $value to byte view
  1923.      *
  1924.      * @param    double   the value to format
  1925.      * @param    integer  the sensitiveness
  1926.      * @param    integer  the number of decimals to retain
  1927.      *
  1928.      * @return   array    the formatted value and its unit
  1929.      *
  1930.      * @access  public
  1931.      *
  1932.      * @author   staybyte
  1933.      * @version  1.2 - 18 July 2002
  1934.      */
  1935.     function PMA_formatByteDown($value, $limes = 6, $comma = 0)
  1936.     {
  1937.         $dh           = pow(10, $comma);
  1938.         $li           = pow(10, $limes);
  1939.         $return_value = $value;
  1940.         $unit         = $GLOBALS['byteUnits'][0];
  1941.  
  1942.         for ( $d = 6, $ex = 15; $d >= 1; $d--, $ex-=3 ) {
  1943.             if (isset($GLOBALS['byteUnits'][$d]) && $value >= $li * pow(10, $ex)) {
  1944.                 $value = round($value / ( pow(1024, $d) / $dh) ) /$dh;
  1945.                 $unit = $GLOBALS['byteUnits'][$d];
  1946.                 break 1;
  1947.             } // end if
  1948.         } // end for
  1949.  
  1950.         if ($unit != $GLOBALS['byteUnits'][0]) {
  1951.             $return_value = number_format($value, $comma, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
  1952.         } else {
  1953.             $return_value = number_format($value, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
  1954.         }
  1955.  
  1956.         return array($return_value, $unit);
  1957.     } // end of the 'PMA_formatByteDown' function
  1958.  
  1959.  
  1960.     /**
  1961.      * Extracts ENUM / SET options from a type definition string
  1962.      *
  1963.      * @param   string   The column type definition
  1964.      *
  1965.      * @return  array    The options or
  1966.      *          boolean  FALSE in case of an error.
  1967.      *
  1968.      * @author  rabus
  1969.      */
  1970.     function PMA_getEnumSetOptions($type_def) {
  1971.         $open = strpos($type_def, '(');
  1972.         $close = strrpos($type_def, ')');
  1973.         if (!$open || !$close) {
  1974.             return FALSE;
  1975.         }
  1976.         $options = substr($type_def, $open + 2, $close - $open - 3);
  1977.         $options = explode('\',\'', $options);
  1978.         return $options;
  1979.     } // end of the 'PMA_getEnumSetOptions' function
  1980.  
  1981.     /**
  1982.      * Writes localised date
  1983.      *
  1984.      * @param   string   the current timestamp
  1985.      *
  1986.      * @return  string   the formatted date
  1987.      *
  1988.      * @access  public
  1989.      */
  1990.     function PMA_localisedDate($timestamp = -1, $format = '')
  1991.     {
  1992.         global $datefmt, $month, $day_of_week;
  1993.  
  1994.         if ($format == '') {
  1995.             $format = $datefmt;
  1996.         }
  1997.  
  1998.         if ($timestamp == -1) {
  1999.             $timestamp = time();
  2000.         }
  2001.  
  2002.         $date = preg_replace('@%[aA]@', $day_of_week[(int)strftime('%w', $timestamp)], $format);
  2003.         $date = preg_replace('@%[bB]@', $month[(int)strftime('%m', $timestamp)-1], $date);
  2004.  
  2005.         return strftime($date, $timestamp);
  2006.     } // end of the 'PMA_localisedDate()' function
  2007.  
  2008.  
  2009.     /**
  2010.      * Prints out a tab for tabbed navigation.
  2011.      * If the variables $link and $args ar left empty, an inactive tab is created
  2012.      *
  2013.      * @param   string  the text to be displayed as link
  2014.      * @param   string  main link file, e.g. "test.php"
  2015.      * @param   string  link arguments
  2016.      * @param   string  link attributes
  2017.      * @param   string  include '?' even though no attributes are set. Can be set empty, should be '?'.
  2018.      * @param   boolean force display TAB as active
  2019.      *
  2020.      * @return  string  two table cells, the first beeing a separator, the second the tab itself
  2021.      *
  2022.      * @access  public
  2023.      */
  2024. /* replaced with a newer function
  2025.    2004-05-20 by Michael Keck <mail_at_michaelkeck_dot_de>
  2026. */
  2027. /*
  2028.     function PMA_printTab($text, $link, $args = '', $attr = '', $class = '', $sep = '?', $active = false) {
  2029.         global $PHP_SELF, $cfg;
  2030.         global $db_details_links_count_tabs;
  2031.  
  2032.         if (!empty($class)) {
  2033.             $class = ' class="' . $class . '"';
  2034.             $addclass = ' ' . $class;
  2035.         } else {
  2036.             $addclass = '';
  2037.         }
  2038.  
  2039.         if (((!isset($GLOBALS['active_page']) && basename($PHP_SELF) == $link) ||
  2040.                 $active ||
  2041.                 (isset($GLOBALS['active_page']) && $GLOBALS['active_page'] == $link)
  2042.             ) && ($text != $GLOBALS['strEmpty'] && $text != $GLOBALS['strDrop'])) {
  2043.             $addclass .= ' activetab';
  2044.         }
  2045.  
  2046.         $db_details_links_count_tabs++;
  2047.  
  2048.         if ($cfg['LightTabs']) {
  2049.             $out = '';
  2050.             if (strlen($link) > 0) {
  2051.                 $out .= '<a class="tab" href="' . $link . $sep . $args . '"' . $attr . $class . '>'
  2052.                      .  '' . $text . '</a>';
  2053.             } else {
  2054.                 $out .= '<span class="tab">' . $text . '</span>';
  2055.             }
  2056.             $out = '[ ' . $out . ' ]   ';
  2057.         } else {
  2058.             $out     = "\n" . '        '
  2059.                      . '<td class="tab nowrap' . $addclass . '">'
  2060.                      . "\n" . '            ';
  2061.             if (strlen($link) > 0) {
  2062.                 $out .= '<a href="' . $link . $sep . $args . '"' . $attr .  $class . '>'
  2063.                      .  $text . '</a>';
  2064.             } else {
  2065.                 $out .= $text;
  2066.             }
  2067.             $out     .= "\n" . '        '
  2068.                      .  '</td>'
  2069.                      .  "\n" . '        '
  2070.                      .  '<td width="8"> </td>';
  2071.         }
  2072.  
  2073.         return $out;
  2074.     } // end of the 'PMA_printTab()' function
  2075. */
  2076. // the new one:
  2077.     function PMA_printTab($text, $link, $args = '', $attr = '', $class = '', $sep = '?', $active = false) {
  2078.         global $PHP_SELF, $cfg;
  2079.         global $db_details_links_count_tabs;
  2080.         $addclass = '';
  2081.         if (((!isset($GLOBALS['active_page']) && basename($PHP_SELF) == $link) ||
  2082.                 $active ||
  2083.                 (isset($GLOBALS['active_page']) && $GLOBALS['active_page'] == $link)
  2084.             ) && ($text != $GLOBALS['strEmpty'] && $text != $GLOBALS['strDrop'])) {
  2085.             $addclass = 'Active';
  2086.         }
  2087.         if ($text == $GLOBALS['strEmpty'] && $text == $GLOBALS['strDrop']) $addclass = 'Drop';
  2088.         if (empty($class)){
  2089.             if (empty($addclass)) { $addclass = 'Normal'; }
  2090.         } else { $addclass = $class; }
  2091.  
  2092.         $db_details_links_count_tabs++;
  2093.  
  2094.         if ($cfg['LightTabs']) {
  2095.             $out = '';
  2096.             if (!empty($link)) {
  2097.                 $out .= '<a class="tab" href="' . $link . $sep . $args . '"' . $attr . $class . '>'
  2098.                      .  '' . $text . '</a>';
  2099.             } else {
  2100.                 $out .= '<span class="tab">' . $text . '</span>';
  2101.             }
  2102.             $out = '[ ' . $out . ' ]   ';
  2103.         } else {
  2104.             $out     = "\n" . '        '
  2105.                      . '<td class="nav' . $addclass . '" nowrap="nowrap">'
  2106.                      . "\n" . '            ';
  2107.             if (!empty($link)) {
  2108.                 $out .= '<a href="' . $link . $sep . $args . '"' . $attr . '>'
  2109.                      .  $text . '</a>';
  2110.             } else {
  2111.                 $out .= $text;
  2112.             }
  2113.             $out     .= "\n" . '        '
  2114.                      .  '</td>'
  2115.                      .  "\n" . '        '
  2116.                      .  '<td class="navSpacer"><img src="' . $GLOBALS['pmaThemeImage'] . 'spacer.png' . '" width="1" height="1" border="0" alt="" /></td>';
  2117.         }
  2118.  
  2119.         return $out;
  2120.     } // end of the 'PMA_printTab()' function
  2121.  
  2122.  
  2123.     /**
  2124.      * Displays a link, or a button if the link's URL is too large, to
  2125.      * accommodate some browsers' limitations
  2126.      *
  2127.      * @param  string  the URL
  2128.      * @param  string  the link message
  2129.      * @param  string  js confirmation
  2130.      * @param  boolean we set this to FALSE when we are already in a form,
  2131.      *                 to avoid generating nested forms
  2132.      *
  2133.      * @return string  the results to be echoed or saved in an array
  2134.      */
  2135.     function PMA_linkOrButton($url, $message, $js_conf, $allow_button = TRUE)
  2136.     {
  2137.         // previously the limit was set to 2047, it seems 1000 is better
  2138.         if (strlen($url) <= 1000) {
  2139.             $onclick_url        = (empty($js_conf) ? '' : ' onclick="return confirmLink(this, \'' . $js_conf . '\')"');
  2140.             $link_or_button     = '        <a href="' . $url . '"' . $onclick_url . '>' . "\n"
  2141.                                 . '           ' . $message . '</a>' . "\n";
  2142.         }
  2143.         elseif ($allow_button) {
  2144.             $edit_url_parts     = parse_url($url);
  2145.             $query_parts        = explode('&', $edit_url_parts['query']);
  2146.             $link_or_button     = '        <form action="'
  2147.                                 . $edit_url_parts['path']
  2148.                                 . '" method="post">' . "\n";
  2149.             foreach ($query_parts AS $query_pair) {
  2150.                 list($eachvar, $eachval) = explode('=', $query_pair);
  2151.                 $link_or_button .= '            <input type="hidden" name="' . str_replace('amp;', '', $eachvar) . '" value="' . htmlspecialchars(urldecode($eachval)) . '" />' . "\n";
  2152.             } // end while
  2153.  
  2154.             if (stristr($message, '<img')) {
  2155.                 $link_or_button     .= '            <input type="image" src="' . preg_replace('@^.*src="(.*)".*$@si', '\1', $message) . '" value="'
  2156.                                     . htmlspecialchars(preg_replace('@^.*alt="(.*)".*$@si', '\1', $message)) . '" />' . "\n" . '</form>' . "\n";
  2157.             } else {
  2158.                 $link_or_button     .= '            <input type="submit" value="'
  2159.                                     . htmlspecialchars($message) . '" />' . "\n" . '</form>' . "\n";
  2160.             }
  2161.         } else {
  2162.             $link_or_button = ' <dfn title="' . $GLOBALS['strNeedPrimaryKey'] . '">?</dfn> ';
  2163.         } // end if... else...
  2164.  
  2165.             return $link_or_button;
  2166.     } // end of the 'PMA_linkOrButton()' function
  2167.  
  2168.  
  2169.     /**
  2170.      * Returns a given timespan value in a readable format.
  2171.      *
  2172.      * @param  int     the timespan
  2173.      *
  2174.      * @return string  the formatted value
  2175.      */
  2176.     function PMA_timespanFormat($seconds)
  2177.     {
  2178.         $return_string = '';
  2179.         $days = floor($seconds / 86400);
  2180.         if ($days > 0) {
  2181.             $seconds -= $days * 86400;
  2182.         }
  2183.         $hours = floor($seconds / 3600);
  2184.         if ($days > 0 || $hours > 0) {
  2185.             $seconds -= $hours * 3600;
  2186.         }
  2187.         $minutes = floor($seconds / 60);
  2188.         if ($days > 0 || $hours > 0 || $minutes > 0) {
  2189.             $seconds -= $minutes * 60;
  2190.         }
  2191.         return sprintf($GLOBALS['timespanfmt'], (string)$days, (string)$hours, (string)$minutes, (string)$seconds);
  2192.     }
  2193.  
  2194.     /**
  2195.      * Takes a string and outputs each character on a line for itself. Used mainly for horizontalflipped display mode.
  2196.      * Takes care of special html-characters.
  2197.      * Fulfills todo-item http://sourceforge.net/tracker/index.php?func=detail&aid=544361&group_id=23067&atid=377411
  2198.      *
  2199.      * @param   string   The string
  2200.      * @param   string   The Separator (defaults to "<br />\n")
  2201.      *
  2202.      * @access  public
  2203.      * @author  Garvin Hicking <me@supergarv.de>
  2204.      * @return  string      The flipped string
  2205.      */
  2206.     function PMA_flipstring($string, $Separator = "<br />\n") {
  2207.         $format_string = '';
  2208.         $charbuff = false;
  2209.  
  2210.         for ($i = 0; $i < strlen($string); $i++) {
  2211.             $char = $string{$i};
  2212.             $append = false;
  2213.  
  2214.             if ($char == '&') {
  2215.                 $format_string .= $charbuff;
  2216.                 $charbuff = $char;
  2217.                 $append = true;
  2218.             } elseif (!empty($charbuff)) {
  2219.                 $charbuff .= $char;
  2220.             } elseif ($char == ';' && !empty($charbuff)) {
  2221.                 $format_string .= $charbuff;
  2222.                 $charbuff = false;
  2223.                 $append = true;
  2224.             } else {
  2225.                 $format_string .= $char;
  2226.                 $append = true;
  2227.             }
  2228.  
  2229.             if ($append && ($i != strlen($string))) {
  2230.                 $format_string .= $Separator;
  2231.             }
  2232.         }
  2233.  
  2234.         return $format_string;
  2235.     }
  2236.  
  2237.  
  2238.     /**
  2239.      * Function added to avoid path disclosures.
  2240.      * Called by each script that needs parameters, it displays
  2241.      * an error message and, by default, stops the execution.
  2242.      *
  2243.      * Not sure we could use a strMissingParameter message here,
  2244.      * would have to check if the error message file is always available
  2245.      *
  2246.      * @param   array   The names of the parameters needed by the calling
  2247.      *                  script.
  2248.      * @param   boolean Stop the execution?
  2249.      *                  (Set this manually to FALSE in the calling script
  2250.      *                   until you know all needed parameters to check).
  2251.      *
  2252.      * @access  public
  2253.      * @author  Marc Delisle (lem9@users.sourceforge.net)
  2254.      */
  2255.     function PMA_checkParameters($params, $die = TRUE) {
  2256.         global $PHP_SELF;
  2257.  
  2258.         $reported_script_name = basename($PHP_SELF);
  2259.         $found_error = FALSE;
  2260.         $error_message = '';
  2261.  
  2262.         foreach ($params AS $param) {
  2263.             if (!isset($GLOBALS[$param])) {
  2264.                 $error_message .= $reported_script_name . ': Missing parameter: ' . $param . ' <a href="./Documentation.html#faqmissingparameters" target="documentation"> (FAQ 2.8)</a><br />';
  2265.                 $found_error = TRUE;
  2266.             }
  2267.         }
  2268.         if ($found_error) {
  2269.             require_once('./libraries/header_meta_style.inc.php');
  2270.             echo '</head><body><p>' . $error_message . '</p></body></html>';
  2271.             if ($die) {
  2272.                 exit();
  2273.             }
  2274.         }
  2275.     } // end function
  2276.  
  2277.     // Kanji encoding convert feature appended by Y.Kawada (2002/2/20)
  2278.     if (@function_exists('mb_convert_encoding')
  2279.         && strpos(' ' . $lang, 'ja-')
  2280.         && file_exists('./libraries/kanji-encoding.lib.php')) {
  2281.         require_once('./libraries/kanji-encoding.lib.php');
  2282.         define('PMA_MULTIBYTE_ENCODING', 1);
  2283.     } // end if
  2284.  
  2285.     /**
  2286.      * Function to check valid extension of file. It accepts entered
  2287.      * extensions and bz2 and gz if supported.
  2288.      *
  2289.      * @param   string  File name to be tested.
  2290.      * @param   string  Extension that is valid.
  2291.      *
  2292.      * @access  public
  2293.      * @author  Michal Cihar (nijel@users.sourceforge.net)
  2294.      * @return  bool    Whether extension is valid
  2295.      */
  2296.     function PMA_checkFileExtensions($file, $extension) {
  2297.         if (substr($file, -1 * strlen($extension)) == $extension) {
  2298.             return TRUE;
  2299.         }
  2300.         if ($GLOBALS['cfg']['GZipDump'] && @function_exists('gzopen')) {
  2301.             if (substr($file, -3 - strlen($extension)) == $extension . '.gz') {
  2302.                 return TRUE;
  2303.             }
  2304.         }
  2305.         if ($GLOBALS['cfg']['BZipDump'] && @function_exists('bzdecompress')) {
  2306.             if (substr($file, -4 - strlen($extension)) == $extension . '.bz2') {
  2307.                 return TRUE;
  2308.             }
  2309.         }
  2310.         return FALSE;
  2311.     } // end function
  2312.  
  2313.     /**
  2314.      * Function to generate unique condition for specified row.
  2315.      *
  2316.      * @param   resource    handle for current query
  2317.      * @param   integer     number of fields
  2318.      * @param   array       meta information about fields
  2319.      * @param   array       current row
  2320.      *
  2321.      * @access  public
  2322.      * @author  Michal Cihar (michal@cihar.com)
  2323.      * @return  string      calculated condition
  2324.      */
  2325.     function PMA_getUvaCondition($handle, $fields_cnt, $fields_meta, $row) {
  2326.  
  2327.         $primary_key              = '';
  2328.         $unique_key               = '';
  2329.         $uva_nonprimary_condition = '';
  2330.  
  2331.         for ($i = 0; $i < $fields_cnt; ++$i) {
  2332.             $field_flags = PMA_DBI_field_flags($handle, $i);
  2333.             $meta      = $fields_meta[$i];
  2334.             // do not use an alias in a condition
  2335.             $column_for_condition = $meta->name;
  2336.             if (isset($analyzed_sql[0]['select_expr']) && is_array($analyzed_sql[0]['select_expr'])) {
  2337.                 foreach ($analyzed_sql[0]['select_expr'] AS $select_expr_position => $select_expr) {
  2338.                     $alias = $analyzed_sql[0]['select_expr'][$select_expr_position]['alias'];
  2339.                     if (!empty($alias)) {
  2340.                         $true_column = $analyzed_sql[0]['select_expr'][$select_expr_position]['column'];
  2341.                         if ($alias == $meta->name) {
  2342.                             $column_for_condition = $true_column;
  2343.                         } // end if
  2344.                     } // end if
  2345.                 } // end while
  2346.             }
  2347.  
  2348.             // to fix the bug where float fields (primary or not)
  2349.             // can't be matched because of the imprecision of
  2350.             // floating comparison, use CONCAT
  2351.             // (also, the syntax "CONCAT(field) IS NULL"
  2352.             // that we need on the next "if" will work)
  2353.             if ($meta->type == 'real') {
  2354.                 $condition = ' CONCAT(' . PMA_backquote($column_for_condition) . ') ';
  2355.             } else {
  2356.                 // string and blob fields have to be converted using
  2357.                 // the system character set (always utf8) since
  2358.                 // mysql4.1 can use different charset for fields.
  2359.                 if (PMA_MYSQL_INT_VERSION >= 40100 && ($meta->type == 'string' || $meta->type == 'blob')) {
  2360.                     $condition = ' CONVERT(' . PMA_backquote($column_for_condition) . ' USING utf8) ';
  2361.                 } else {
  2362.                     $condition = ' ' . PMA_backquote($column_for_condition) . ' ';
  2363.                 }
  2364.             } // end if... else...
  2365.  
  2366.             if (!isset($row[$i]) || is_null($row[$i])) {
  2367.                 $condition .= 'IS NULL AND';
  2368.             } else {
  2369.                 // timestamp is numeric on some MySQL 4.1
  2370.                 if ($meta->numeric && $meta->type != 'timestamp') {
  2371.                     $condition .= '= ' . $row[$i] . ' AND';
  2372.                 } elseif ($meta->type == 'blob'
  2373.                     // hexify only if this is a true not empty BLOB
  2374.                      && stristr($field_flags, 'BINARY')
  2375.                      && !empty($row[$i])) {
  2376.                         // use a CAST if possible, to avoid problems
  2377.                         // if the field contains wildcard characters % or _
  2378.                         if (PMA_MYSQL_INT_VERSION < 40002) {
  2379.                             $condition .= 'LIKE 0x' . bin2hex($row[$i]). ' AND';
  2380.                         } else {
  2381.                             $condition .= '= CAST(0x' . bin2hex($row[$i]). ' AS BINARY) AND';
  2382.                         }
  2383.                 } else {
  2384.                     $condition .= '= \'' . PMA_sqlAddslashes($row[$i], FALSE, TRUE) . '\' AND';
  2385.                 }
  2386.             }
  2387.             if ($meta->primary_key > 0) {
  2388.                 $primary_key .= $condition;
  2389.             } else if ($meta->unique_key > 0) {
  2390.                 $unique_key  .= $condition;
  2391.             }
  2392.             $uva_nonprimary_condition .= $condition;
  2393.         } // end for
  2394.  
  2395.         // Correction uva 19991216: prefer primary or unique keys
  2396.         // for condition, but use conjunction of all values if no
  2397.         // primary key
  2398.         if ($primary_key) {
  2399.             $uva_condition = $primary_key;
  2400.         } else if ($unique_key) {
  2401.             $uva_condition = $unique_key;
  2402.         } else {
  2403.             $uva_condition = $uva_nonprimary_condition;
  2404.         }
  2405.  
  2406.         return preg_replace('|\s?AND$|', '', $uva_condition);
  2407.     } // end function
  2408.  
  2409.     /**
  2410.      * Function to generate unique condition for specified row.
  2411.      *
  2412.      * @param   string      name of button element
  2413.      * @param   string      class of button element
  2414.      * @param   string      name of image element
  2415.      * @param   string      text to display
  2416.      * @param   string      image to display
  2417.      *
  2418.      * @access  public
  2419.      * @author  Michal Cihar (michal@cihar.com)
  2420.      */
  2421.     function PMA_buttonOrImage($button_name, $button_class, $image_name, $text, $image) {
  2422.         global $pmaThemeImage, $propicon;
  2423.  
  2424.         /* Opera has trouble with <input type="image"> */
  2425.         /* IE has trouble with <button> */
  2426.         if (PMA_USR_BROWSER_AGENT != 'IE') {
  2427.             echo '<button class="' . $button_class . '" type="submit" name="' . $button_name . '" value="' . $text . '" title="' . $text . '">' . "\n"
  2428.                . '<img src="' . $pmaThemeImage . $image . '" title="' . $text . '" alt="' . $text . '" width="16" height="16" />' . (($propicon == 'both') ? ' ' . $text : '') . "\n"
  2429.                . '</button>' . "\n";
  2430.         } else {
  2431.             echo '<input type="image" name="' . $image_name . '" value="' .$text . '" title="' . $text . '" src="' . $pmaThemeImage . $image . '" />'  . (($propicon == 'both') ? ' ' . $text : '') . "\n";
  2432.         }
  2433.     } // end function
  2434.  
  2435.     /**
  2436.      * Generate a pagination selector for browsing resultsets
  2437.      *
  2438.      * @param   string      URL for the JavaScript
  2439.      * @param   string      Number of rows in the pagination set
  2440.      * @param   string      current page number
  2441.      * @param   string      number of total pages
  2442.      * @param   string      If the number of pages is lower than this
  2443.      *                      variable, no pages will be ommitted in
  2444.      *                      pagination
  2445.      * @param   string      How many rows at the beginning should always
  2446.      *                      be shown?
  2447.      * @param   string      How many rows at the end should always
  2448.      *                      be shown?
  2449.      * @param   string      Percentage of calculation page offsets to
  2450.      *                      hop to a next page
  2451.      * @param   string      Near the current page, how many pages should
  2452.      *                      be considered "nearby" and displayed as
  2453.      *                      well?
  2454.      *
  2455.      * @access  public
  2456.      * @author  Garvin Hicking (pma@supergarv.de)
  2457.      */
  2458.     function PMA_pageselector($url, $rows, $pageNow = 1, $nbTotalPage = 1, $showAll = 200, $sliceStart = 5, $sliceEnd = 5, $percent = 20, $range = 10) {
  2459.         $gotopage = '<br />' . $GLOBALS['strPageNumber']
  2460.                   . '<select name="goToPage" onchange="goToUrl(this, \'' . $url . '\');">' . "\n";
  2461.         if ($nbTotalPage < $showAll) {
  2462.             $pages = range(1, $nbTotalPage);
  2463.         } else {
  2464.             $pages = array();
  2465.  
  2466.             // Always show first X pages
  2467.             for ($i = 1; $i <= $sliceStart; $i++) {
  2468.                 $pages[] = $i;
  2469.             }
  2470.  
  2471.             // Always show last X pages
  2472.             for ($i = $nbTotalPage - $sliceEnd; $i <= $nbTotalPage; $i++) {
  2473.                 $pages[] = $i;
  2474.             }
  2475.  
  2476.             // garvin: Based on the number of results we add the specified $percent percentate to each page number,
  2477.             // so that we have a representing page number every now and then to immideately jump to specific pages.
  2478.             // As soon as we get near our currently chosen page ($pageNow - $range), every page number will be
  2479.             // shown.
  2480.             $i = $sliceStart;
  2481.             $x = $nbTotalPage - $sliceEnd;
  2482.             $met_boundary = false;
  2483.             while($i <= $x) {
  2484.                 if ($i >= ($pageNow - $range) && $i <= ($pageNow + $range)) {
  2485.                     // If our pageselector comes near the current page, we use 1 counter increments
  2486.                     $i++;
  2487.                     $met_boundary = true;
  2488.                 } else {
  2489.                     // We add the percentate increment to our current page to hop to the next one in range
  2490.                     $i = $i + floor($nbTotalPage / $percent);
  2491.  
  2492.                     // Make sure that we do not cross our boundaries.
  2493.                     if ($i > ($pageNow - $range) && !$met_boundary) {
  2494.                         $i = $pageNow - $range;
  2495.                     }
  2496.                 }
  2497.  
  2498.                 if ($i > 0 && $i <= $x) {
  2499.                     $pages[] = $i;
  2500.                 }
  2501.             }
  2502.  
  2503.             // Since because of ellipsing of the current page some numbers may be double,
  2504.             // we unify our array:
  2505.             sort($pages);
  2506.             $pages = array_unique($pages);
  2507.         }
  2508.  
  2509.         foreach($pages AS $i) {
  2510.             if ($i == $pageNow) {
  2511.                 $selected = 'selected="selected" style="font-weight: bold"';
  2512.             } else {
  2513.                 $selected = '';
  2514.             }
  2515.             $gotopage .= '                <option ' . $selected . ' value="' . (($i - 1) * $rows) . '">' . $i . '</option>' . "\n";
  2516.         }
  2517.  
  2518.         $gotopage .= ' </select>';
  2519.  
  2520.         return $gotopage;
  2521.     } // end function
  2522.  
  2523.  
  2524.     function PMA_generateAlterTable($oldcol, $newcol, $full_field_type, $collation, $null, $default, $default_current_timestamp, $extra, $comment='') {
  2525.  
  2526.         // $default_current_timestamp has priority over $default
  2527.         // TODO: on the interface, some js to clear the default value
  2528.         // when the default current_timestamp is checked
  2529.  
  2530.         $query = PMA_backquote($oldcol) . ' ' . PMA_backquote($newcol) . ' '
  2531.             . $full_field_type;
  2532.         if (PMA_MYSQL_INT_VERSION >= 40100 && !empty($collation) && $collation != 'NULL' && preg_match('@^(TINYTEXT|TEXT|MEDIUMTEXT|LONGTEXT|VARCHAR\(\d+\)|CHAR\(\d+\))$@i', $full_field_type)) {
  2533.             $query .= PMA_generateCharsetQueryPart($collation);
  2534.         }
  2535.  
  2536.         if (!empty($null)) {
  2537.             $query .= ' NOT NULL';
  2538.         } else {
  2539.             $query .= ' NULL';
  2540.         }
  2541.  
  2542.         if ($default_current_timestamp && strpos(' ' . strtoupper($full_field_type),'TIMESTAMP') == 1) {
  2543.             $query .= ' DEFAULT CURRENT_TIMESTAMP';
  2544.             // 0 is empty in PHP
  2545.         } elseif (!empty($default) || $default == '0') {
  2546.             if (strtoupper($default) == 'NULL') {
  2547.                 $query .= ' DEFAULT NULL';
  2548.             } else {
  2549.                 $query .= ' DEFAULT \'' . PMA_sqlAddslashes($default) . '\'';
  2550.             }
  2551.         }
  2552.  
  2553.         if (!empty($extra)) {
  2554.             $query .= ' ' . $extra;
  2555.         }
  2556.         if (PMA_MYSQL_INT_VERSION >= 40100 && !empty($comment)) {
  2557.             $query .= " COMMENT '" . PMA_sqlAddslashes($comment) . "'";
  2558.         }
  2559.         return $query;
  2560.     } // end function
  2561.  
  2562. } // end if: minimal common.lib needed?
  2563.  
  2564. ?>
  2565.